目标是创建支持优先级任务的线程池。 所以我需要编写一些数据结构来支持线程安全的优先级队列。 当然,我们可以编写大锁并使用std :: priority_queue。但这不是那么有效。
有一个想法是实现带有并发提取的二进制堆(每个元素都有自己的自旋锁,并且有一个全局shared_mutex,当我们更改堆大小时会被写入锁定,当我们堆积节点时读取锁定,以及当我们交换时并比较我们锁定其自旋锁的节点),但有许多潜在的死锁能力,我仍然不知道如何避免它们。
是否有更好的数据结构可以更容易地使线程安全?或者是否有任何已经实施的堆我可以调查?
答案 0 :(得分:4)
你真的应该实现你能找到的最简单的东西,用锁保护它,并在你的应用程序中测试它。除非你每秒击中它数千次,否则锁的开销几乎肯定与你的应用程序的性能无关。如果您的队列相对较小,则尤其如此。
我的建议是从std::priority_queue
开始,围绕它进行锁定,然后试一试。
如果您确实认为需要无锁并发优先级队列,请查看Concurrent mutable priority queue。
答案 1 :(得分:2)
不要这么快就假设无锁优先级队列比互斥锁更快。正如您所见,任何显着复杂性的无锁结构往往具有复杂性,涉及大量原子操作。在现代处理器上,由于在多核CPU中保持内存视图一致性的复杂性,这些原子操作变得相对多得多,速度慢得多。
在这种情况下,如果一个简单的二进制堆周围的简单自旋锁不是很多,比无锁堆实现快得多,无论争用程度如何,我都会感到很惊讶。