我将消费者/生产者问题与我的应用程序分开,以确保我的线程能够正常工作。
我有一个生产者线程和一个消费者线程池:在我的应用程序中,一个线程接受连接并在四个队列之一中排队(在我的自定义结构中),并从队列中弹出四个线程并处理之前排队的连接;在这里,我的队列将包含1到4之间的随机int
,没有自定义结构。
四个mutex
确保每个队列的数据保护(在打印队列大小时,为终端上的cout
加一个互斥锁); priority_queue
用于同步四个队列中的删除。生产者线程在正确的队列中推送新的int
值,然后在priority_queue
中推送,这样当线程想要阅读时,他首先需要pop()
来自priority_queue
为了理解已经推送了什么队列(因为它被排序,在一些随机推送后我的priority_queue
看起来像1 1 1 2 3 3 3 3 4 4
,所以消费者线程会pop()
,看到值{{1并且理解它必须从队列1
中删除。
为什么有四个队列?因为每个队列都有自己的优先级(1 = max,4 = minimum),所以在从队列2中删除元素之前,应该删除队列1中的元素;所有其他队列的理由相同。从这里开始随机推送值从1到4,应该没有饥饿。
在Ubuntu 14.04 x86_64上编译:1
,gcc版本4.8.4。
问题:除了调度程序导致的奇怪输出外,消费者线程没有按照我的意愿行事,因为正如您在下面的输出中所看到的那样,它没有优先从队列1,但删除不遵循优先级(队列1最大,队列4分钟)。
我想在不使用外部库的情况下实现我的目标,没有g++ -std=c++11 -o producer-consumer-multiqueue producer-consumer-multiqueue.cpp -pthread
et similia 。
boost
代码:这是我的完整测试文件,可编译和可执行文件:
(0 0 1 0) // (elements in queue 1, in queue 2, in queue 3, in queue 4)
(1 0 1 0)
(1 1 1 0)
(0 0 0 0)
(0 0 0 0)
(0 0 0 0)
(1 0 0 0)
(2 0 0 0)
(2 1 0 0)
(1 1 0 1)
(1 0 0 1)
(1 0 0 0)
(1 0 0 0)
(0 0 0 0)
(1 0 0 0)
...CTRL+c
答案 0 :(得分:0)
我在您的代码中看到以下问题:
print
锁定很长一段时间,其他获得元素的线程可以是第一个获得print
锁定的线程。queue1
,然后第一个线程由调度程序关闭,第二个线程开始工作。它还会弹出优先级队列,然后继续弹出queue2
(第一个线程关闭时)。我会遵循评论中的建议并使用单priority_queue<std::pair<int,int>>
,其中std::pair<int,int>
的第一个元素是优先级,第二个元素是有效负载。这将有助于您处理问题2。
对于问题1,您应该在与pop
内容相同的锁定下打印内容。