两个 notify_one() 方法在 Cygwin 上不起作用

Two notify_one() methods do not work on Cygwin

在 Cygwin 上,当使用两个不同的条件处理两个不同函数中的线程时,主线程不会通知 notify_one() 调用中的等待线程之一。在 visual studio 上,此方法工作正常。 Cygwin 不允许主线程处理两个不同的 unique_locks 吗?例如:

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();
}

然后在这个主线程上等待:

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
}

这是使线程 运行 并在调用 notify_one() 之前等待的主要函数:

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();
    }
}

您的代码不能保证 freeway.wait(block); 发生在 freeway.notify_one(); 之前。因此,线程可能只有在您尝试通知它之后才开始等待,然后永远等待。

事实上,锁保证 freeway.notify_one(); 发生在 freeway.wait(block); 之前,因为 someWaitingOtherThread 将首先必须等到 someFunction 中的锁被释放,这会发生在 notify_one 次调用之后。

从技术上讲,intersection.notify_one(); 也不能保证这一点,尽管在大多数情况下等待一秒钟在实践中可能会起作用(但如果系统处于高负载下,我不会打赌它.)

尽管如此,wait 总是会偶尔唤醒,因此两个编译器都运行正常。

此外,由于您使用的是 notify_one 而不是 notify_all,五个线程中的四个可能根本无法弥补。

我将 user17732522 的答案标记为正确,因为它是与我的线程问题相关的正确答案,但我发现主要问题是 Cygwin 如何在程序中处理我的文本文件,这导致输入不正确并最终所有线程崩溃(线程正常工作后)。我认为这是我的线程的问题,但我应该先寻找更简单的答案,然后再假设它是其他问题。