【发布时间】:2011-04-25 03:28:54
【问题描述】:
我已经使用 Boost 线程和条件实现了一个基本的线程生产者-消费者(线程 1 = 生产者,线程 2 = 消费者)。我经常无限期地陷入 wait() 中。我真的看不出这里有什么问题。下面是一些伪代码:
// main class
class Main {
public:
void AddToQueue(...someData...)
{
boost::mutex::scoped_lock lock(m_mutex);
m_queue.push_back(new QueueItem(...someData...));
m_cond.notify_one();
}
void RemoveQueuedItem(...someCond...)
{
// i'm wondering if this could cause the trouble?
boost::mutex::scoped_lock lock(m_mutex);
// erase a item matching condition (some code not shown,
// but should be fairly self-explanatory -- IsMatch()
// simply looks at a flag of QueueItem
m_queue.erase(std::remove_if(m_queue.being(), m_queue.end(),
boost::bind(&Main::IsMatch, this, _1, someCond), m_queue.end());
}
friend void WorkerThread(Main* m);
private:
boost::ptr_deque<QueueItem> m_queue;
boost::mutex m_mutex;
boost::condition m_cond;
};
// worker thread
void WorkerThread(Main* m)
{
typedef boost::ptr_deque<QueueItem>::auto_type RelType;
RelType queueItem;
while(!shutDown) {
{ // begin mutex scope
boost::mutex::scoped_lock lock(m->m_mutex);
while(m->m_queue.empty()) {
m->m_cond.wait(lock); // <- stuck here forever quite often!
}
queueItem = m->m_queue->pop_front(); // pop & take ptr ownership
} // end mutex scope
// ... do stuff with queueItem
// ...
// ... queueItem is deleted when it leaves scope & we loop around
}
}
一些附加信息:
- 使用 Boost v1.44
- 在 Linux 和 Android 中出现问题;我还不确定它是否发生在 Windows 中
有什么想法吗?
更新: 我相信我已经隔离了这个问题。确认后我会进一步更新,希望是明天。
更新 2: 事实证明,上述代码没有问题。我依赖于 AddToQueue() 的底层 API - 在工作线程中处理数据并将其返回给 API 时,它有一个循环错误,它会再次调用 AddToQueue() ......现在已修复;-)
【问题讨论】:
-
您上面的代码缺少您在条件变量上等待的部分。也粘贴一下。
-
在我上面的工作线程(消费者)中,你会看到一段时间(queue_is_empty()) { cond.wait(lock); } 你指的是这个吗?
标签: c++ boost conditional-statements wait producer-consumer