两个 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 如何在程序中处理我的文本文件,这导致输入不正确并最终所有线程崩溃(线程正常工作后)。我认为这是我的线程的问题,但我应该先寻找更简单的答案,然后再假设它是其他问题。
在 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 如何在程序中处理我的文本文件,这导致输入不正确并最终所有线程崩溃(线程正常工作后)。我认为这是我的线程的问题,但我应该先寻找更简单的答案,然后再假设它是其他问题。