Home > Back-end >  Two notify_one() methods do not work on Cygwin
Two notify_one() methods do not work on Cygwin

Time:05-04

On Cygwin, when dealing with threads in two different functions using two different conditionals, the main thread does not notify one of the waiting threads on the notify_one() call. On visual studio, this method works fine. Does Cygwin not allow a main thread to handle two different unique_locks? For example:

mutex m_mutex;
mutex b_mutex;
condition_variable intersection;
condition_variable freeway;

void someFunction(){
  unique_lock<mutex> mlock(m_mutex);
  unique_lock<mutex> block(b_mutex);
  intersection.notify_one(); 
  freeway.notify_one();
}

Then wait on this main thread:

void someWaitingThreadFunc(){
  unique_lock<mutex> mlock(m_mutex);
  intersection.wait(mlock); //one thread waiting
  someWaitingOtherThread(); //thread then moves to new function where it 
  //encounters second wait
}

void someWaitingOtherThread(){
  unique_lock<mutex> block(b_mutex);
  freeway.wait(block); //a different thread waiting for something else
}

Here is the main function that makes the threads run and wait before notify_one() is called:

int main(){
 vector<thread> vts;

    for (int i = 1; i <= 5; i  ) {
        vts.push_back(thread(someWaitingThreadFunc));
    }
    Sleep(1);
    thread mainThread(someFunction);
    mainThread.join();

    for (int i = 0; i < 5; i  ) {
        vts[i].join();
    }
}

CodePudding user response:

Your code does not assure that freeway.wait(block); happens before freeway.notify_one();. Therefore the thread may start waiting only after you tried to notify it and then wait forever.

In fact, the locks guarantee that freeway.notify_one(); happens before freeway.wait(block);, because someWaitingOtherThread will first have to wait until the lock in someFunction is released, which happens after the notify_one calls.

It technically also doesn't assure this for intersection.notify_one();, although waiting for one second is likely to work in practice in most cases (I wouldn't bet on it though if the system is under high load.)

Nonetheless, wait can always wake up sporadically, so both compilers are behaving correctly.

Also, since you are using notify_one instead of notify_all, four of the five threads may never make up at all.

CodePudding user response:

I am marking user17732522's answer correct as it is the correct answer in relation to my thread problem, however I found out the main problem was how Cygwin was handling my text file in the program, which was causing incorrect input and eventual crashing of all the threads (after the threads worked correctly). I thought this was a problem with my threads, but I should have looked for the simpler answer first before assuming it was something else.

  • Related