我正在尝试设计一个可以由多个读/写线程同时访问的队列。我更喜欢使用2个互斥量,每个用于读写。写入很简单,锁定写入互斥锁,附加数据,解锁并完成。
问题在于阅读。如果in队列中没有数据,我希望我的线程等到数据可用。一种显而易见的方法是获取读取互斥锁并在每N个时钟周期内保持轮询队列,但这显然不是最好的方法。这让我了解条件变量。有没有人有任何好的资源讨论使用条件变量(最好是基于pthreads)在C ++中阻塞队列实现?
具体来说,我看到以下问题:
答案 0 :(得分:3)
我有一个使用http://danborn.net/code/中相同互斥锁的实现,但就像我之前提到的那样,因为它使用了一个条件变量,它也使用了1个互斥锁。
这是升级版本,再次使用单个互斥锁:http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html
答案 1 :(得分:2)
我认为你误解了一些东西 - 即使没有线程在等待那个条件,调用pthread_cond_signal
也是完全合法的。
此外,在多线程编程的上下文中,将某些内容称为“读取”操作 通常意味着它不会改变共享资源的状态。如果通过“阅读” 你的意思是“从队列的头部删除一个项目”,这会改变状态 队列(换句话说,它也是一个“写”。)根据你的情况,用“消费者和制作者”而不是“读者和作者”来思考可能会更好。
单个互斥锁(以保证对队列的独占访问)和两个条件变量(“可用数据”,“可用空间”)应该足以满足您的需要。 (如果 队列可以动态增长,你不需要“可用空间可用”条件变量; 我只是提到完整性。)
如果您的阅读主题严格读者(也就是说,他们不以任何方式修改共享队列数据结构,例如通过弹出一个项目队列),pthread_rwlock
系列调用也可能是一个合适的解决方案。在这个范例中,有读锁(多个读取器可以同时保持,但强制写入器阻塞直到读取器完成),并写锁(这确保了持有写锁的线程的独占访问,阻止任何其他编写器和读者。)
答案 2 :(得分:2)
this C++ threading blog post的示例12-3应该为您提供参考实现,但我认为您自己的危险接近成功。解决您的具体问题:
pthread_cond_broadcast
导致一个主要问题:群大象充电,其中所有 n 线程都醒来并开始在缓存之间拉入内存,即使只有其中一个可能会取得进展。它会起作用,但效率不高。pthread_cond_wait
来电必须释放读取互斥锁;这是唯一的要求,而且这是唯一需要与条件变量交互的互斥锁。从#3开始,你的想法存在一个主要问题:作者线程必须锁定两者读取和写入互斥锁。如果没有,会发生什么当队列大小为1并且你有一个读者和一个作家同时行动时?
答案 3 :(得分:1)
您是否考虑过使用信号量而不是条件变量?信号量是等待的,即使没有线程在等待,也可以表示“队列非空”状态。
答案 4 :(得分:0)
一个简单的boost :: condition示例位于here。