【发布时间】:2015-10-04 16:10:59
【问题描述】:
我有一个使用 std::atomics 以类似于 Herb Sutters CPPCon2014 谈话的方式实现的无锁单生产者多消费者队列。
有时,生产者的速度太慢,无法满足所有消费者的需求,因此消费者可能会挨饿。我想防止饥饿的消费者排队等候,因此我为10ms 添加了睡眠。这个值是任意的,不是最优的。我想使用一个信号,一旦队列中再次有空闲插槽,消费者就可以发送给生产者。在基于锁的实现中,我自然会使用std::condition_variable 来完成这项任务。但是现在在我的无锁实现中,我不确定引入mutex 是否是正确的设计选择,只能使用std::condition_variable。
我只是想问你,在这种情况下,mutex 是否正确?
编辑:我有一个从不睡觉的制作人。并且有多个消费者,如果他们饿了就去睡觉。因此整个系统总是在进步,因此我认为它是无锁的。
我目前的解决方案是在消费者 GetData 函数中做到这一点:std::unique_lock<std::mutex> lk(_idleMutex);
_readSetAvailableCV.wait(lk);
一旦新数据准备好,这在生产者线程中:_readSetAvailableCV.notify_all();
【问题讨论】:
-
一个带有信号的睡眠线程不是无锁的,几乎按照定义。你明白无锁主要是为了保证线程调度和进度,而不是“更快”,对吧?您到底需要什么无锁保证?
-
我想我不明白。如果是消费者挨饿,为什么队列中有空闲槽时他们会通知生产者?
-
但是,如果您确实需要一个具有多个写入器的变量,这意味着至少有一个写入器准备好使用更新,这听起来像是一个原子标志。
-
@Lorehead OP 想要一个无锁队列......但有锁可以阻止空闲读者旋转。并且想知道如何在没有锁的情况下做到这一点。
-
@BenjaminMenkuec 您应该使用互斥锁,因为互斥锁通过取消调度竞争线程来最小化争用。原子和无锁算法无法避免争用惩罚。
标签: c++ multithreading c++11