Multithreads not behaving as expected - c++

#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
std::mutex g_m;
std::string messageGlobal = "";
void threadFunc() // run in the log thread
{
while (1)
{
g_m.lock();
if (messageGlobal != "")
{
// logging takes a long time
sleep(10000)
cout << messageGlobal << endl;
messageGlobal = "";
}
g_m.unlock();
}
}
// logging api
void log(const string& message)
{
g_m.lock();
messageGlobal = message;
g_m.unlock();
}
int main()
{
std::thread th(threadFunc);
log("Hello world!");
log("Hello World2!");
log("Hello World3!");
log("Hello World4!");
// Important work
th.join();
return 0;
}
New to threading here and I don't understand why only the last message is being printed.
The two threads here are main thread and an extra thread which runs permanently and outputs to the screen whenever there is a message to be printed.
Would appreciate if someone shows me where I went wrong.
Edit: the goal is for the code in "important code" to execute while the very long logging function takes place.

As other people suggested, you'd better use a queue to hold the messages and synchronize the access of the message queue between threads. However, here is a simple fix of your code here:
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
std::mutex g_m;
std::string messageGlobal = "";
bool g_all_done = false;
void threadFunc() // run in the log thread
{
while (1)
{
g_m.lock();
if (messageGlobal != "")
{
cout << messageGlobal << endl;
messageGlobal = "";
}
bool all_done = g_all_done;
g_m.unlock();
if (all_done) break;
}
}
// logging api
void log(const string& message)
{
bool logged = false;
do {
g_m.lock();
if (messageGlobal == "") {
messageGlobal = message;
logged = true;
}
g_m.unlock();
} while(!logged);
}
void all_done() {
g_m.lock();
g_all_done = true;
g_m.unlock();
}
int main()
{
std::thread th(threadFunc);
log("Hello world!");
log("Hello World2!");
log("Hello World3!");
log("Hello World4!");
all_done(); // this tells the print thread to finish.
th.join();
return 0;
}

Would appreciate if someone shows me where I went wrong.
You are wrong in assumption that threads would lock mutex in order, which is not guaranteed. So what happened that the same thread (main) locked the mutex multiple times and modified the message multiple times and second thread only had a chance to print the last message. To make it work you should make main thread to wait until message is emptied and only then to publish again, but most probably you should do that using condition variable as otherwise you would peg CPU doing this in code as written. And even better to create a queue of log messages and only wait when queue is full.
Note that you are missing condition for log thread to finish so th.join(); would hang.
Here is example on how it could work with single message:
std::mutex g_m;
std::condition_variable g_notifyLog;
std::condition_variable g_notifyMain;
bool g_done = false;
std::string messageGlobal = "";
void threadFunc() // run in the log thread
{
while (1)
{
std::lock_guard<std::mutex> lk( g_m );
g_notifyLog.wait( g_m, []() { return !messageGlobal.empty() || g_done; } );
if( g_done ) break;
cout << messageGlobal << endl;
messageGlobal = "";
g_notifyMain.notify_one();
}
}
// logging api
void log(const string& message)
{
std::lock_guard<std::mutex> lk( g_m );
g_notifyMain.wait( g_m, []() { return messageGlobal.empty(); } );
messageGlobal = message;
g_notifyLog.notify_one();
}
void stop_log()
{
std::lock_guard<std::mutex> lk( g_m );
g_done = true;
g_notifyLog.notify_one();
}

You didn't implement any mechanism that ensures that the threads operate interleaved. It is much more likely that the thread that unlocked mutex will be the one to lock it in the next moment as locking mutex/unlocking mutexes are fast operations unless sleep/wait is triggered.
Furthermore, the ThreadFunc is an endless loop. So it theoretically the program might just run the loop repeatedly without letting any execution of log to trigger.
You need to utilise std::condition_variable to signal between threads when data is available for logging and rewrite log method so it won't overwrite existing data-to-be-printed.

Related

Can multiple threads join the same boost::thread?

pthreads has undefined behavior if multiple threads try to join the same thread:
If multiple threads simultaneously try to join with the same thread,
the results are undefined.
Is the same true for boost::threads? The documentation does not appears to specify this.
If it is undefined, then what would be a clean way for multiple threads to wait on one thread completing?
If it is undefined, then what would be a clean way for multiple threads to wait on one thread completing?
The clean way would be for that one thread to inform the others that it is complete. A packaged_task contains a future which can be waited on, which can help us here.
Here's one way of doing that. I have used std::thread and std::packaged_task, but you could use the boost equivalents just as well.
#include <thread>
#include <mutex>
#include <future>
#include <vector>
#include <iostream>
void emit(const char* msg) {
static std::mutex m;
std::lock_guard<std::mutex> l(m);
std::cout << msg << std::endl;
std::cout.flush();
}
int main()
{
using namespace std;
auto one_task = std::packaged_task<void()>([]{
emit("waiting...");
std::this_thread::sleep_for(std::chrono::microseconds(500));
emit("wait over!");
});
// note: convert future to a shared_future so we can pass it
// to two subordinate threads simultaneously
auto one_done = std::shared_future<void>(one_task.get_future());
auto one = std::thread(std::move(one_task));
std::vector<std::thread> many;
many.emplace_back([one_done] {
one_done.wait();
// do my thing here
emit("starting thread 1");
});
many.emplace_back([one_done] {
one_done.wait();
// do my thing here
emit("starting thread 2");
});
one.join();
for (auto& t : many) {
t.join();
}
cout << "Hello, World" << endl;
return 0;
}
expected output:
waiting...
wait over!
starting thread 2
starting thread 1
Hello, World
I ended up using a boost::condition_variable... roughly:
class thread_wrapper {
boost::mutex mutex;
boost::condition_variable thread_done_condition;
bool thread_done = false;
void the_func() {
// ...
// end of the thread
{
boost:unique_lock<boost::mutex> lock(mutex);
thread_done = true;
}
thread_done_condition.notify_all();
}
void wait_until_done() {
boost::unique_lock<boost::mutex> lock(mutex);
thread_done_condition.wait(lock, [this]{ return thread_done; });
}
}
Then multiple callers can safely call wait_until_done().
It strikes me now that something like the following would also have worked:
class thread_wrapper {
public:
thread_wrapper() : thread([this]() { this->the_func(); }) { }
void wait_until_done() {
boost::unique_lock<boost::mutex> lock(join_mutex);
thread.join();
}
private:
void the_func() {
// ...
}
boost::mutex join_mutex;
boost::thread thread;
}

terminating a running boost thread

I currently have a boost thread as such
class foo
{
private:
boost::shared_ptr<boost::thread> t;
public:
foo()
{
t = boost::make_shared<boost::thread>(&foo::SomeMethod,this);
}
void SomeMethod()
{
while(true)
{
.... //Does some work
boost::this_thread::sleep(boost::posix_time::milliseconds(5000)); //sleep for 5 seconds
}
}
void stopThread()
{
//Elegant and instant way of stopping thread t
}
}
I have read from this post that you have to define interruption points however I am not sure if I understand how that would fit in my scenario. I am looking for a safe elegant way that will ensure that thread t is terminated
You can't ever safely terminate a thread, you just need to tell it from the outside that it should stop. If you interrupt a thread, you don't know where you interrupted it and you could leave the system in an unknown state.
Instead of looping forever, you can check a variable (make sure it's thread safe though!) inside the thread's loop to see if the thread should exit. What I do in work threads is I have them wait on a condition variable, and then when there's work they wake up and do work, but when they're awake they also check the "shutdown" flag to see if they should exit.
A snippet of my code:
//-----------------------------------------------------------------------------
void Manager::ThreadMain() {
unique_lock<mutex> lock( m_work_mutex, std::defer_lock );
while( true ) {
lock.lock();
while( m_work_queue.empty() && !m_shutdown ) {
m_work_signal.wait( lock );
}
if( !m_work_queue.empty() ) {
// (process work...)
continue;
}
// quit if no work left and shutdown flag set.
if( m_shutdown ) return;
}
}
You could maybe get away with something like:
std::atomic<bool> stop_thread = false;
void SomeMethod()
{
while( !stop_thread )
{
.... //Does some work
boost::this_thread::sleep(boost::posix_time::milliseconds(5000)); //sleep for 5 seconds
}
}
void stopThread()
{
stop_thread = true;
// join thread (wait for it to stop.)
t->join();
}
And let me tell you, sometimes it isn't easy to make something safely exit. A few weeks ago I had a big struggle with threaded console input. I ended up having to handle raw windows console events and translating them into keystrokes myself, just so I could simultaneously intercept my custom shutdown event.
Use boost::thread interrupt()
#include <iostream>
#include <boost/thread.hpp>
#include <boost/chrono.hpp>
class Foo
{
private:
boost::shared_ptr<boost::thread> t;
public:
Foo()
{
t = boost::make_shared<boost::thread>(&Foo::SomeMethod, this);
}
void SomeMethod()
{
std::cout << "thread starts" << std::endl;
while(true) {
std::cout << "." << std::endl;
boost::this_thread::sleep(boost::posix_time::seconds(1));
}
}
void stopThread()
{
t->interrupt();
t->join();
std::cout << "thread stopped" << std::endl;
}
};
int main()
{
Foo foo;
boost::this_thread::sleep(boost::posix_time::seconds(5));
foo.stopThread();
return 0;
}
Execute it
# g++ f.cpp -lboost_thread && ./a.out
thread starts
.
.
.
.
.
thread stopped

C++11: condition variable only works for once

I have this piece of code:
std::unique_lock<std::mutex> lock(m_mutex);
for(;;)
{
// wait for input notification
m_event.wait(lock);
// if there is an input pin doesn't have any data, just wait
for(DataPinIn* ptr:m_in_ports)
if(ptr->m_data_dup==NULL)
continue;
// do work
Work(&m_in_ports,&m_out_ports);
// this might need a lock, we'll see
for(DataPinIn* ptr:m_in_ports)
{
// reduce the data refcnt before we lose it
ptr->FreeData();
ptr->m_data_dup=NULL;
std::cout<<"ptr:"<<ptr<<"set to 0\n";
}
}
in which m_event is a condition_variable.
It waits for notification from another thread and then does some works. But I found out that this only succeeds for the first time and it blocks on m_event.wait(lock) forever, no matter how many times m_event.notify_one() is called. How should I solve this?
Thanks in advance.
You are experiencing the common scenario 'spurious wakeup' (please consult wiki) which condition_variable is desgined to solve.
Please read the sample code in this article: http://www.cplusplus.com/reference/condition_variable/condition_variable/.
Usually condition_variable must be used together with a certain variable to avoid spurious wakeups; that's how the synchronization method is named.
Below is a better piece of sample code:
#include <condition_variable>
#include <mutex>
#include <thread>
#include <iostream>
#include <queue>
#include <chrono>
int main()
{
std::queue<int> produced_nums;
std::mutex m;
std::condition_variable cond_var;
bool done = false;
bool notified = false;
std::thread producer([&]() {
for (int i = 0; i < 5; ++i) {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::unique_lock<std::mutex> lock(m);
std::cout << "producing " << i << '\n';
produced_nums.push(i);
notified = true;
cond_var.notify_one();
}
done = true;
cond_var.notify_one();
});
std::thread consumer([&]() {
std::unique_lock<std::mutex> lock(m);
while (!done) {
while (!notified) { // loop to avoid spurious wakeups
cond_var.wait(lock);
}
while (!produced_nums.empty()) {
std::cout << "consuming " << produced_nums.front() << '\n';
produced_nums.pop();
}
notified = false;
}
});
producer.join();
consumer.join();
}
It turns out that a flag variable ruined everything and the threading part is working correctly.

Multithreading and using events

My program has three threads, and I am trying to learn about synchronization and thread safety. Below I outline what the different threads do, but I would like to learn how to use events instead to trigger each process in the different threads instead of infinitely reading (which is giving me concurrency issues).
Googling throws up many options but I'm not sure what is best to implement in this case - could you point the direction to a standard method/event that I could learn to best implement this?
I am doing this on VS 2012, and ideally I would not use external libraries e.g. boost.
Thread 1: receives a message and pushes it into a global queue, queue<my_class> msg_in.
Thread 2: on infinite loop (i.e. while(1) ); waits till if (!msg_in.empty()), does some processing, and pushes it into a global map<map<queue<my_class>>> msg_out.
while (1)
{
if (!msg_in.empty())
{
//processes
msg_map[i][j].push(); //i and j are int (irrelevant here)
}
}
Thread 3:
while (1)
{
if (msg_map.find(i) != msg_map.end())
{
if (!msg_map[i].find(j)->second.empty())
{
//processes
}
}
}
Your problems is a producer consumer problem. You can use condition variables for your events. There is one example of it here: http://en.cppreference.com/w/cpp/thread/condition_variable
I have adapted it to your example if your need it.
#include "MainThread.h"
#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <atomic>
#include <condition_variable>
std::mutex m;
std::condition_variable cv;
bool ready = false;
bool processed = false;
void worker_thread(unsigned int threadNum)
{
// Wait until main() sends data
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{return ready;});
}
std::cout << "Worker thread "<<threadNum <<" is processing data"<<std::endl;
// Send data back to main()
{
std::lock_guard<std::mutex> lk(m);
processed = true;
std::cout << "Worker thread "<< threadNum <<" signals data processing completed\n";
}
cv.notify_one();
}
int initializeData()
{
// send data to the worker thread
{
std::lock_guard<std::mutex> lk(m);
ready = true;
std::cout << "Data initialized"<<std::endl;
}
cv.notify_one();
return 0;
}
int consumerThread(unsigned int nbThreads)
{
std::atomic<unsigned int> nbConsumedthreads=0;
while (nbConsumedthreads<nbThreads)
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{return processed;});
std::cout<<"Data processed counter="<<nbConsumedthreads << " "<< std::endl;
++nbConsumedthreads;
cv.notify_one();
}
return 0;
}
int main()
{
const unsigned int nbThreads=3;
std::thread worker1(worker_thread,1);
std::thread worker2(worker_thread,2);
std::thread worker3(worker_thread,3);
std::thread init(initializeData);
std::thread consume(consumerThread, nbThreads);
worker1.join();
worker2.join();
worker3.join();
init.join();
consume.join();
return 0;
}
Hope that helps, tell me if you need more info.

Returning values from pthread asynchronously at regular intervals

The main() function creates a thread that is supposed to live until the user wishes to exit the program. The thread needs to return values to the main functions at periodic intervals. I tried doing something like this, but hasn't worked well -
std::queue<std::string> q;
void start_thread(int num)
{
std::string str;
//Do some processing
q.push(str);
}
int main()
{
//Thread initialization
int i;
//Start thread
pthread_create(&m_thread,NULL,start_thread,static_cast<void *>i);
while(true)
{
if(q.front())
{
std::cout<<q.front();
return 0;
}
}
//Destroy thread.....
return 0;
}
Any suggestions?
It is not safe to read and write from STL containers concurrently. You need a lock to synchronize access (see pthread_mutex_t).
Your thread pushes a single value into the queue. You seem to be expecting periodic values, so you'll want to modify start_thread to include a loop that calls queue.push.
The return 0; in the consumer loop will exit main() when it finds a value in the queue. You'll always read a single value and exit your program. You should remove that return.
Using if (q.front()) is not the way to test if your queue has values (front assumes at least one element exists). Try if (!q.empty()).
Your while(true) loop is gonna spin your processor somethin' nasty. You should look at condition variables to wait for values in the queue in a nice manner.
try locking a mutex before calling push() / front() on the queue.
Here is a working example of what it looks like you were trying to accomplish:
#include <iostream>
#include <queue>
#include <vector>
#include <semaphore.h>
#include <pthread.h>
struct ThreadData
{
sem_t sem;
pthread_mutex_t mut;
std::queue<std::string> q;
};
void *start_thread(void *num)
{
ThreadData *td = reinterpret_cast<ThreadData *>(num);
std::vector<std::string> v;
std::vector<std::string>::iterator i;
// create some data
v.push_back("one");
v.push_back("two");
v.push_back("three");
v.push_back("four");
i = v.begin();
// pump strings out until no more data
while (i != v.end())
{
// lock the resource and put string in the queue
pthread_mutex_lock(&td->mut);
td->q.push(*i);
pthread_mutex_unlock(&td->mut);
// signal activity
sem_post(&td->sem);
sleep(1);
++i;
}
// signal activity
sem_post(&td->sem);
}
int main()
{
bool exitFlag = false;
pthread_t m_thread;
ThreadData td;
// initialize semaphore to empty
sem_init(&td.sem, 0, 0);
// initialize mutex
pthread_mutex_init(&td.mut, NULL);
//Start thread
if (pthread_create(&m_thread, NULL, start_thread, static_cast<void *>(&td)) != 0)
{
exitFlag = true;
}
while (!exitFlag)
{
if (sem_wait(&td.sem) == 0)
{
pthread_mutex_lock(&td.mut);
if (td.q.empty())
{
exitFlag = true;
}
else
{
std::cout << td.q.front() << std::endl;
td.q.pop();
}
pthread_mutex_unlock(&td.mut);
}
else
{
// something bad happened
exitFlag = true;
}
}
return 0;
}