寻找使两个线程与条件变量同步的方法,并创建了一个简单的示例进行练习。
想想我在进行同步时搞砸了,因为消费者一直在等待来自简历的信号。
即使存在cv.notify_one()
,return counter != 0
lambda内的行也不会被触发,我完全无法理解为什么。
#include <iostream>
#include <mutex>
#include <thread>
#include <chrono>
using namespace std::chrono_literals;
int main(int, char**)
{
std::mutex mx;
std::condition_variable cv;
int counter;
std::thread producer( [ & ] ( )
{
while( true )
{
std::lock_guard<std::mutex> lock( mx );
std::cout << "adding task" << std::endl;
std::this_thread::sleep_for(1s);
++counter;
cv.notify_one();
}
});
std::thread consumer( [ & ] ( )
{
while( true )
{
std::unique_lock<std::mutex> lock( mx );
cv.wait( lock, [ & ] ( )
{
return counter > 0;
});
std::cout << "Executing" << std::endl;
std::this_thread::sleep_for(.5s);
--counter;
}
});
consumer.join();
producer.join();
return 0;
}
问题显然是公平的,如添加一条线所示
std::this_thread::sleep_for(0.01s);
在生产者获得互斥量之前。
大多数操作系统不会为互斥量提供任何公平保证。
有很多方法可以解决公平问题。如果您知道如何处理,则可以在此处停止。
在您的情况下,假设您的生产者和消费者实际上并没有花费半秒钟或更多的时间将工作放入队列中,并且生产者实际上没有无限量的工作,那么您就不需要根本不用担心。如果操作系统在竞争激烈的时刻偏向生产者而不是消费者,则队列会被填满(或者最终所有待处理的作业最终会进入队列),迫使生产者等待,释放互斥量并允许消费者轮流使用。
请注意,在具有最大队列大小的生产者/消费者方案中,您实际上需要两个条件变量-满和空条件。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句