我正在编写一个具有事件队列的应用程序。我的目的是以这样的方式创建它,即多个线程可以写入并且一个线程可以从队列中读取,并将弹出元素的处理移交给另一个线程,以便不再阻止后续弹出。我使用了一个锁和一个条件变量来从队列中推送和弹出项目:
void Publisher::popEvent(boost::shared_ptr<Event>& event) {
boost::mutex::scoped_lock lock(queueMutex);
while(eventQueue.empty())
{
queueConditionVariable.wait(lock);
}
event = eventQueue.front();
eventQueue.pop();
lock.unlock();
}
void Publisher::pushEvent(boost::shared_ptr<Event> event) {
boost::mutex::scoped_lock lock(queueMutex);
eventQueue.push(event);
lock.unlock();
queueConditionVariable.notify_one();
}
在Publisher类的构造函数中(只创建了一个实例),我启动了一个线程,它将迭代循环直到捕获到notify_one(),然后启动另一个线程来处理弹出的事件从队列中:
在构造函数中:
publishthreadGroup = boost::shared_ptr<boost::thread_group> (new boost::thread_group());
publishthreadGroup->create_thread(boost::bind(queueProcessor, this));
queueProcessor方法:
void queueProcessor(Publisher* agent) {
while(true) {
boost::shared_ptr<Event> event;
agent->getEvent(event);
agent->publishthreadGroup->create_thread(boost::bind(dispatcher, agent, event));
}
}
并且在调度程序方法中,完成相关处理并且经处理的信息通过thrift发布到服务器。在程序存在之前调用的另一个方法,即在主线程中,我调用join_all(),以便主线程等待直到线程完成。
在这个实现中,在发出调度程序的线程之后,在上面的while循环中,我遇到了死锁/挂起。运行代码似乎被卡住了。这个实现中的问题是什么?我有没有更清洁,更好的方式来做我想做的事情? (多个生成器和一个消费者线程遍历队列并将元素处理切换到不同的线程)
谢谢!
答案 0 :(得分:1)
似乎queueProcessor
函数将永远运行,并且运行它的线程永远不会退出。该函数创建的任何线程都将完成它们的工作并退出,但是这个线程 - 在publishthreadGroup
中创建的第一个线程 - 具有无法停止的while(true)
循环。因此,对join_all()
的调用将永远等待。你能创建一些其他标志变量来触发该函数来退出循环并返回吗?那应该是诀窍!