我正在学习C++中的多线程。我有一个关于条件变量的问题。如果我有这样的代码:
std::condition_variable cvS;
std::condition_variable cvR;
std::condition_variable cv;
std::mutex gMtx;
int countm = 0;
void SenderS()
{
std::unique_lock<std::mutex> lck(gMtx);
while(countm >= 5){
std::cout << std::this_thread::get_id() <<"exceedin S" << std::endl;
cv.wait(lck); //or cvS.wait(lck);
}
countm++;
std::cout<< std::this_thread::get_id() << "S"<< countm << std::endl;
lck.unlock();
cv.notify_one(); //or cvR.notify_one();
}
void ReceiverS()
{
std::unique_lock<std::mutex> lck(gMtx);
while(countm <= 0){
std::cout << std::this_thread::get_id() <<"exceedin R" << std::endl;
cv.wait(lck); //or cvR.wait(lck);
}
countm--;
std::cout << std::this_thread::get_id() <<"R" << countm << std::endl;
lck.unlock();
cv.notify_one(); //or cvS.notify_one();
}
在这种情况下,使用一个或两个条件变量有什么区别吗?一般来说,对于生产者-消费者模型,我应该使用一个或两个条件变量吗?
另外,cvR.notify_one()
是否只通知执行cvR.wait()
的线程?
2条答案
按热度按时间jvlzgdj91#
这是我对这个question给出的答案,我认为在这里也适用。我认为你需要两个条件变量或一个原子标志。
带互斥和两个条件变量的乒乓
这是使用互斥体和条件变量的规范乒乓。注意1)你需要两个条件变量来使ping-pong工作,2)你必须小心地将输出语句放在一个仍然持有锁的块中。你的代码很接近。
这将导致以下输出。
单原子旗乒乓
根据您的平台,使用原子标志而不是条件变量可能更有性能(并且更容易理解)。这将产生与上面相同的输出。
jhdbpxl92#
根据我个人的分析,如果使用单个条件变量,应该使用
notify_all()
来唤醒所有等待的线程,以避免唤醒错误的线程。如果使用两个条件变量,使用notify_one()
来唤醒“另一边”的一个线程应该没问题。我不知道这是不是一个正确的规则。