Second thread is never triggered - c++

I've been struggling with a multithreading issue for a bit. I've written some simple code to try and isolate the issue and I'm not finding it. What's happening is that the first thread is being woken up with data being sent to it, but second one never does. They each have their own condition_variable yet it doesn't seem to matter. Ultimately, what I'm trying to do is have a few long running threads that do a single dedicated task when needed, and staying in a wait state when not needed. And running them each in their own thread is important and a requirement.
Here's the code:
#include <glib.h>
#include <string>
#include <mutex>
#include <condition_variable>
#include <unistd.h>
#define NUM_THREADS 2
bool DEBUG = true;
pthread_t threads[NUM_THREADS];
std::mutex m_0;
std::mutex m_1;
std::condition_variable cov_0;
std::condition_variable cov_1;
bool dataReady_0 = false;
bool dataReady_1 = false;
bool keepRunning[NUM_THREADS] = { true };
void date_update (guint source_id, const char *json_data) {
if (DEBUG) {
start_threads(2);
sleep(2);
DEBUG = false;
}
g_print("From source id=%d\n", source_id);
switch (source_id) {
case 0:
dataReady_0 = true;
cov_0.notify_one();
break;
case 1:
dataReady_1 = true;
cov_1.notify_one();
break;
}
}
void start_threads (int thread_count) {
int rc;
switch (thread_count) {
case 2:
rc = pthread_create(&threads[1], nullptr, custom_thread_1, nullptr);
if (rc) {
g_print("Error:unable to create thread(1), return code(%d)\n", rc);
}
case 1:
rc = pthread_create(&threads[0], nullptr, custom_thread_0, nullptr);
if (rc) {
g_print("Error:unable to create thread(0), return code(%d)\n", rc);
}
}
}
void *custom_thread_0 (void *pVoid) {
g_print("Created thread for source id=0\n");
while (keepRunning[0]) {
// Wait until date_update() sends data
std::unique_lock<std::mutex> lck(m_0);
cov_0.wait(lck, [&]{return dataReady_0;});
dataReady_0 = false;
g_print("THREAD=0, DATA RECEIVED\n");
lck.unlock();
}
pthread_exit(nullptr);
}
void *custom_thread_1 (void *pVoid) {
g_print("Created thread for source id=1\n");
while (keepRunning[1]) {
// Wait until date_update() sends data
std::unique_lock<std::mutex> lck(m_1);
cov_1.wait(lck, [&]{return dataReady_1;});
dataReady_1 = false;
g_print("THREAD=1, DATA RECEIVED\n");
lck.unlock();
}
pthread_exit(nullptr);
}
Here's the output. As you can see the data_update function gets the "data" from the calling function for both source 0 and source 1, but only thread 0 ever seems to process anything. I'm at a bit of a loss as to the source of the problem.
Sending data for source id=1
From source id=1
Sending data for source id=0
From source id=0
THREAD=0, DATA RECEIVED
Sending data for source id=1
From source id=1
Sending data for source id=0
From source id=0
THREAD=0, DATA RECEIVED
Sending data for source id=1
From source id=1
Sending data for source id=0
From source id=0
THREAD=0, DATA RECEIVED
I'm sure I'm just missing a minor detail somewhere, but I'm fully willing to accept that perhaps I do not understand C/C++ threading correctly.

The 2nd thread is exiting because the keepRunning state flag is false. It's usually a good first step in debugging threads to log the start and exit of all threads.
But you have a much less obvious problem.
It does not appear that the appropriate mutex is held when the value of the condition variable's predicate is changed in date_update().
I'll break that down a bit more.
When cov_0.wait() is called, the predicate used is [&]{return dataReady_0;} (*), and the unique_lock passed is holding the mutex m_0. This means that whenever the value of the predicate might change, the mutex m_0 must be held.
This predicate is quite simple and will change value whenever the global variable dataReady_0 changes value.
In date_update() there is code to change the value of dataReady_0 and the mutex m_0 is not held when doing this. There should be a scoped_lock or unique_lock in the block that changes the global variable's state.
It will still mostly work without this, but you have a race! It will fail eventually!
The condition variable may check and see that the predicate is false, then another thread changes the predicate's value and does a notify, and then the first thread waits on the condition variable. It misses the notify because it was not yet waiting when it was sent. The use of the mutex to prevent the predicate from changing in a way that races with the notification is a critical component of what makes this work.
(*) You don't need the capture [&] here. This lambda could be stateless.

You should initialize all elements of the built-in array:
bool keepRunning[2] = { true, true };

Related

C++ Wait for bool to change in another class

I have a Program class and a Browser class.
Inside my Program::Run(), I launch the Browser to start in a separate thread.
However, before I continue with my Run() method, I want to wait for a certain part of the Browser to initialize, thus I need to check if a variable has been set in the browser object.
Used as the thread for the browser
int Program::_Thread_UI_Run() {
...
return Browser->Run();
}
I am using async to run the browser thread and retrieve its return value when it is finished.
int Program::Start() {
std::unique_lock<std::mutex> lck(mtx);
auto t1 = std::async(&Program::_Thread_Browser_Run, this);
cv.wait(lck);
... when wait is released, do stuff
// Thread finishes and returns an exit code for the program
auto res1 = f1.get();
// return res1 as exit code.
}
Browser.cpp class
int Browser::Run()
{
// Initialize many things
...
m_Running = true;
cv.notify_all(); // Notify the waiter back in Program
// This will run for as long as the program is running
while (m_Running)
{
... browser window message loop
}
return exit_code;
}
I have problems setting this up. The program is crashing :/
Do I pass the mutex variable to everything using it? Or just recreate it in every function body?
What about the conditional_variable?
With the current setup the program crashes:
The exception Breakpoint
A breakpoint has been reached.
(0x80000003) occured in the application at location 0x107d07d6.
Hints and help is appreciated
Edit: Updated code to match new suggestions
In browser's .h file: std::atomic_bool m_Running;
int Browser::Run(std::condition_variable& cv)
{
int exit_code = 0;
// Set up, and attain the desired state:
...
m_Running = true;
cv.notify_all();
while (m_Running)
{
// Process things etc
}
return exit_code;
}
int Program::Start()
{
std::mutex m;
std::condition_variable cv;
auto t1 = std::async(&Program::_Thread_UI_Run, this, std::ref(cv));
std::unique_lock<std::mutex> lock(m);
cv.wait(lock);
.... stuff
return t1.get();
}
I have a logger that helps me keep track of how the program is running.
By placing logger calls in crucial places in the code I was able to confirm that the program waits appropiately before continuing. However I still get prompted with
The exception Breakpoint A breakpoint has been reached. (0x80000003)
occured in the application at location 0x107d07d6.
By commenting out //cv.wait(lock); the program resumes to work.. :/
Why would waiting making it crash like that?
You definitely want to use std::condition_variable. It allows you to signal other threads once an operation has complete, so in your case, once the bool has been set:
Browser::Run()
{
// Set some things up, make sure everything is okay:
...
m_Running = true; // Now the thread is, by our standards, running*
// Let other threads know:
cv.notify_all();
// Continue to process thread:
while (m_Running)
{
}
}
And then in your main / other thread:
auto t1 = std::async(&Program::_Thread_Browser_Run, this);
// Wait until we know the thread is actually running. This will pause this thread indefinitely until the condition_variable signals.
cv.wait();
You should pass the std::condition_variable into any function using it, so your code would look more like:
int Browser::Run(std::condition_variable& cv)
{
int exit_code = 0;
// Set up, and attain the desired state:
...
m_Running = true;
cv.notify_all();
while (m_Running)
{
// Process things etc
}
return exit_code;
}
int Program::Start()
{
std::mutex m;
std::condition_variable cv;
auto t1 = std::async(&Program::_Thread_UI_Run, this, std::ref(cv));
std::unique_lock<std::mutex> lock(m);
// Wait until the browser is in the desired state
cv.wait(lock);
// The thread has signalled. At this point, Browser::m_Running = true
// Wait for the browser to exit, and then propagate its exit code
return t1.get();
}
#Richard Hodges raises an excellent point in the comments, which I overlooked: m_Running needs to be std::atomic (or have locking around its use) otherwise both threads may try to use it once. std::condition_variable is thread-safe and doesn't require locking around it.
*Of course the thread is running at that point, I just mean it's in the state you desire

Waiting until another process locks and then unlocks a Win32 mutex

I am trying to tell when a producer process accesses a shared windows mutex. After this happens, I need to lock that same mutex and process the associated data. Is there a build in way in Windows to do this, short of a ridiculous loop?
I know the result of this is doable through creating a custom Windows event in the producer process, but I want to avoid changing this programs code as much as possible.
What I believe will work (in a ridiculously inefficient way) would be this (NOTE: this is not my real code, I know there are like 10 different things very wrong with this; I want to avoid doing anything like this):
#include <Windows.h>
int main() {
HANDLE h = CreateMutex(NULL, 0, "name");
if(!h) return -1;
int locked = 0;
while(true) {
if(locked) {
//can assume it wont be locked longer than a second, but even if it does should work fine
if(WaitForSingleObject(h, 1000) == WAIT_OBJECT_0) {
// do processing...
locked = 0;
ReleaseMutex(h);
}
// oh god this is ugly, and wastes so much CPU...
} else if(!(locked = WaitForSingleObject(h, 0) == WAIT_TIMEOUT)) {
ReleaseMutex(h);
}
}
return 0;
}
If there is an easier way with C++ for whatever reason, my code is actually that. This example was just easier to construct in C.
You will not be able to avoid changing the producer if efficient sharing is needed. Your design is fundamentally flawed for that.
A producer needs to be able to signal a consumer when data is ready to be consumed, and to make sure it does not alter the data while it is busy being consumed. You cannot do that with a single mutex alone.
The best way is to have the producer set an event when data is ready, and have the consumer reset the event when the data has been consumed. Use the mutex only to sync access to the data, not to signal the data's readiness.
#include <Windows.h>
int main()
{
HANDLE readyEvent = CreateEvent(NULL, TRUE, FALSE, "ready");
if (!readyEvent) return -1;
HANDLE mutex = CreateMutex(NULL, FALSE, "name");
if (!mutex) return -1;
while(true)
{
if (WaitForSingleObject(readyEvent, 1000) == WAIT_OBJECT_0)
{
if (WaitForSingleObject(mutex, 1000) == WAIT_OBJECT_0)
{
// process as needed...
ResetEvent(readyEvent);
ReleaseMutex(mutex);
}
}
}
return 0;
}
If you can't change the producer to use an event, then at least add a flag to the data itself. The producer can lock the mutex, update the data and flag, and unlock the mutex. Consumers will then have to periodically lock the mutex, check the flag and read the new data if the flag is set, reset the flag, and unlock the mutex.
#include <Windows.h>
int main()
{
HANDLE mutex = CreateMutex(NULL, FALSE, "name");
if (!mutex) return -1;
while(true)
{
if (WaitForSingleObject(mutex, 1000) == WAIT_OBJECT_0)
{
if (ready)
{
// process as needed...
ready = false;
}
ReleaseMutex(mutex);
}
}
return 0;
}
So either way, your logic will have to be tweaked in both the producer and consumer.
Otherwise, if you can't change the producer at all, then you have no choice but to change the consumer alone to simply check the data for changes peridiodically:
#include <Windows.h>
int main()
{
HANDLE mutex = CreateMutex(NULL, 0, "name");
if (!mutex) return -1;
while(true)
{
if (WaitForSingleObject(mutex, 1000) == WAIT_OBJECT_0)
{
// check data for changes
// process new data as needed
// cache results for next time...
ReleaseMutex(mutex);
}
}
return 0;
}
Tricky. I'm going to answer the underlying question: when is the memory written?
This can be observed via a four step solution:
Inject a DLL in the watched process
Add a vectored exception handler for STATUS_GUARD_PAGE_VIOLATION
Set the guard page bit on the 2 MB memory range (finding it could be a challenge)
From the vectored exception handler, inform your process and re-establish the guard bit (it's one-shot)
You may need only a single guard page if the image is always fully rewritten.

How to use a thread to break a loop in main c++

I am using the following thread in c++ to check if a certain condition is met and if so then it should break the loop. I call the thread in a while loop so I need that to break.
The refresh token is updated by another thread.
void ThreadCheck( void* pParams )
{
if(refresh)
{
continue;
}
}
My while loop:-
while(crun)
{
refresh = false;
_beginthread( ThreadCheck, 0, NULL );
rlutil::setColor(8);
cout<<"Send>> ";
getline(cin, msg); //Make a custom function of this.
if(stricmp(msg.c_str(), "exit")==0)
{
crun = false;
}
else if(msg.empty() || stricmp(msg.c_str()," ")==0)
{
rlutil::setColor(4);
cout<<"Plz enter a valid message!\n";
continue;
} else {
manager('c', msg);
// msg.append("\n");
// chat_out<<msg;
// chat_out.close();
}
cout<<"\n";
}
You cannot modify a value in one thread while another thread is, or might be, accessing it. You need to use some form of synchronization, such as a lock.
You have 2 threads : 1) main, 2) ThreadCheck. Add a mutex so as not to update the 'crun' at the same time and inside the thread update the value to false. That's it
#include <iostream>
#include "/tbb/mutex.h"
#include "/tbb/tbb_thread.h"
using namespace tbb;
typedef mutex myMutex;
static myMutex sm;
int i = 0;
void ThreadCheck( )
{
myMutex::scoped_lock lock;//create a lock
lock.acquire(sm);//Method acquire waits until it can acquire a lock on the mutex
//***only one thread can access the lines from here...***
crun = false;;//update is safe (only one thread can execute the code in this scope) because the mutex locked above protects all lines of code until the lock release.
sleep(1);//simply creating a delay to show that no other thread can update
std::cout<<"ThreadCheck "<<"\n";
//***...to here***
lock.release();//releases the lock (duh!)
}
int main()
{
tbb_thread my_thread(ThreadCheck);//create a thread which executes 'someFunction'
// ... your code
my_thread.join();//This command causes the main thread (which is the 'calling-thread' in this case) to wait until thread1 completes its task.
}

When is it more appropriate to use a pthread barrier instead of a condition wait and broadcast?

I am coding a telemetry system in C++ and have been having some difficulty syncing certain threads with the standard pthread_cond_timedwait and pthread_cond_broadcast.
The problem was that I needed some way for the function that was doing the broadcasting to know if another thread acted on the broadcast.
After some hearty searching I decided I might try using a barrier for the two threads instead. However, I still wanted the timeout functionality of the pthread_cond_timedwait.
Here is basically what I came up with: (However it feels excessive)
Listen Function: Checks for a period of milliseconds to see if an event is currently being triggered.
bool listen(uint8_t eventID, int timeout)
{
int waitCount = 0;
while(waitCount <= timeout)
{
globalEventID = eventID;
if(getUpdateFlag(eventID) == true)
{
pthread_barrier_wait(&barEvent);
return true;
}
threadSleep(); //blocks for 1 millisecond
++waitCount;
}
return false;
}
Trigger Function: Triggers an event for a period of milliseconds by setting an update flag for the triggering period
bool trigger(uint8_t eventID, int timeout)
int waitCount = 0;
while(waitCount <= timeout)
{
setUpdateFlag(eventID, true); //Sets the update flag to true
if(globalEventID == eventID)
{
pthread_barrier_wait(&barEvent);
return true;
}
threadSleep(); //blocks for 1 millisecond
++waitCount;
}
setUpdateFlag(eventID, false);
return false;
}
My questions: Is another way to share information with the broadcaster, or are barriers really the only efficient way? Also, is there another way of getting timeout functionality with barriers?
Based on your described problem:
Specifically, I am trying to let thread1 know that the message it is
waiting for has been parsed and stored in a global list by thread2,
and that thread2 can continue parsing and storing because thread1 will
now copy that message from the list ensuring that thread2 can
overwrite that message with a new version and not disrupt the
operations of thread1.
It sounds like your problem can be solved by having both threads alternately wait on the condition variable. Eg. in thread 1:
pthread_mutex_lock(&mutex);
while (!message_present)
pthread_cond_wait(&cond, &mutex);
copy_message();
message_present = 0;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
process_message();
and in thread 2:
parse_message();
pthread_mutex_lock(&mutex);
while (message_present)
pthread_cond_wait(&cond, &mutex);
store_message();
message_present = 1;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);

Sockets and multithreading

I have an interesting (to me) problem... There are two threads, one for capturing data from std input and sending it through socket to server, and another one which receives data from blocking socket. So, when there's no reply from server, recv() call waits indefenitely, right? But instead of blocking only its calling thread, it blocks the overall process! Why this thing occurs?
boost::mutex nvtMutex;
boost::mutex strMutex;
boost::mutex quitMutex;
bool quit = false;
void *processServerOutput(void *arg)
{
NVT *nvt = (NVT*)arg;
while(1)
{
// Lock the quitMutex before trying to access to quit variable
quitMutex.lock();
if(quit)
{
quitMutex.unlock();
pthread_exit(NULL);
}
else
quitMutex.unlock();
// Receive output from server
nvtMutex.lock();
nvt->receive();
cout << Util::Instance()->iconv("koi8-r", "utf-8", nvt->getOutBuffer());
nvtMutex.unlock();
// Delay
sleep(1);
}
}
void *processUserInput(void *arg)
{
NVT *nvt = (NVT*)arg;
while(1)
{
// Get user's input
//cin.getline(str, 1023);
sleep(3);
strcpy(str, "hello");
// If we type 'quit', exit from thread
if(strcmp(str, "quit") == 0)
{
// Lock quit variable before trying to modify it
quitMutex.lock();
quit = true;
quitMutex.unlock();
// Exit from thread
pthread_exit(NULL);
}
// Send the input to server
nvtMutex.lock();
nvt->writeUserCommand(Util::Instance()->iconv("utf-8", "koi8-r", str));
nvt->send();
nvtMutex.unlock();
}
}
You are holding the nvtMutex inside the call to NVT::recv. Since both threads need to lock the mutex to make it through an iteration, until NVT::recv returns the other thread can't progress.
Without knowing the details of this NVT class, it's impossible to know if you can safely unlock the mutex before calling NVT::recv or if this class does not provide the proper thread safety you need.
If your code is implemented correctly, recv blocks only the thread that invokes it.
If this isn't the case for you, show the minimal code sample that demonstrates the problem.