[英]std::condition_variable thread contention
我有一个问题,我的condition_variables似乎没有互相通知。 从我所阅读的内容来看, condition_variable
无法正常工作的主要原因似乎是因为该锁仅在“等待”线程中使用。 就是说,我下面的代码在wait和notify线程中都使用了互斥锁,但是仍然无法正常运行。
我有什么想念的吗?
谢谢。
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
std::condition_variable cv_one;
std::condition_variable cv_two;
std::mutex m_one;
std::mutex m_two;
void one( )
{
std::unique_lock< std::mutex > lock { m_one };
cv_one.notify_one( );
std::cout << "one" << std::endl;
}
void two( )
{
{
std::unique_lock< std::mutex > lock { m_one };
cv_one.wait( lock );
std::cout << "two" << std::endl;
}
{
std::unique_lock< std::mutex > lock { m_two };
cv_two.notify_one( );
}
}
void three( )
{
std::unique_lock< std::mutex > lock { m_two };
cv_two.wait( lock );
std::cout << "three" << std::endl;
}
int main( int argc, char **argv )
{
std::thread thread_one( one );
std::thread thread_two( two );
std::thread thread_three( three );
std::cin.get( );
cv_one.notify_all( );
thread_three.join( );
thread_two.join( );
thread_one.join( );
return 0;
}
条件变量没有相互通知,因为您在错误的时间进行了通知。 例如,如果one
调用cv_one.notify()
之前 two
呼叫cv_one.wait(lock)
,然后two
将永远阻塞。 据two
所见,没有线程在等待时通知它。 这就是@ v.oddou的意思,通知标志未存储。
std::cin
行起了延迟的作用,这就是为什么输出正确的原因。 所有线程都会延迟等待条件变量的位置,这需要您按下按钮。
在此代码示例中,您可以看到问题的发生,该示例显示了线程在唤醒时开始等待的时间。 我切换到单个字符,以便输出不会出现乱码。
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
std::condition_variable cv_one;
std::condition_variable cv_two;
std::mutex m_one;
std::mutex m_two;
void one()
{
std::unique_lock< std::mutex > lock { m_one };
std::cout << "x" << std::endl;
cv_one.notify_one();
std::cout << "a" << std::endl;
}
void two()
{
{
std::unique_lock< std::mutex > lock { m_one };
std::cout << "y" << std::endl;
cv_one.wait( lock );
std::cout << "b" << std::endl;
}
{
std::unique_lock< std::mutex > lock { m_two };
cv_two.notify_one();
}
}
void three()
{
std::unique_lock< std::mutex > lock { m_two };
std::cout << "z" << std::endl;
cv_two.wait( lock );
std::cout << "c" << std::endl;
}
int main( int argc, char **argv )
{
std::thread thread_one(one);
std::thread thread_two(two);
std::thread thread_three(three);
std::cout << "d" << std::endl;
cv_one.notify_all();
thread_three.join();
thread_two.join();
thread_one.join();
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.