【发布时间】:2018-10-16 08:30:45
【问题描述】:
我有一个生产者线程,它为三个消费者线程生产工作。当工作产生时,生产者线程等待直到消费者线程完成处理工作。然后生产者线程继续处理结果。
#include <condition_variable>
#include <mutex>
#include <boost/thread/barrier.hpp>
#include <vector>
#include <queue>
std::condition_variable cond;
std::mutex mutex;
boost::barrier barrier(4);
std::vector<std::thread> workers;
std::queue<unsigned int> work;
std::queue<unsigned int> results;
void worker();
int main()
{
// 1 producer and 3 consumers
for(unsigned int i = 0; i < 3; i++)
workers.push_back(std::thread(worker));
// Wait here so the three workers can get to cond.wait();
barrier.wait();
std::unique_lock<std::mutex> lock(mutex);
while(true)
{
// Generate work
std::cout << "gen" << std::endl;
for(unsigned int i = 0; i < 10; i++)
work.push(i);
cond.notify_all();
lock.unlock();
barrier.wait();
// Handle the results
while(results.size() > 0)
results.pop();
lock.lock();
}
return 0;
}
void worker()
{
while(true)
{
std::unique_lock<std::mutex> lock(mutex);
while(results.size() == 0)
{
lock.unlock();
barrier.wait();
lock.lock();
cond.wait(lock);
}
// Get work
unsigned int next = work.front();
work.pop();
// Store the result
results.push(next);
lock.unlock();
}
}
问题是在生产者线程开始下一次迭代之前,我需要确保所有消费者线程都进入cond.wait(lock):
- 所有 4 个线程都已到达屏障。屏障被释放,线程可以继续。
- 生产者线程在所有消费者线程到达
cond.wait(lock)之前锁定互斥体。因此,至少有一个消费者线程被lock.lock()阻塞。 - 生产者线程开始下一次迭代,创建工作并通知消费者。由于至少一个消费者线程尚未到达
cond.wait(lock),因此至少一个消费者线程将错过notify_all()。这些线程现在等待下一个notify_all()- 这永远不会到达。 - 下次到达屏障时,至少有一个消费者线程仍在等待下一个
notify_all()。因此屏障不会被解锁并发生死锁。
我该如何解决这种情况?
【问题讨论】:
-
您能评论一下您为什么拒绝我的问题吗?
-
可能是因为你没有minimal reproducible example?
-
这个例子现在应该更好了。
-
我不明白你为什么需要屏障。
produce work => wait until all work resolved => combine the results.还不够吗? -
我怎么能等到所有工作都解决了,而不是循环旋转?
标签: c++ multithreading mutex producer-consumer barrier