我有一个关于C ++(使用Boost线程)并发性的noob问题,我没有找到明确的答案。我有一个在一个单独的线程中运行的worker类。我在一个开始时启动了worker程序只有一次。这个工作者是“懒惰的”,只有当它从调用线程接收它时才进行一些数据编码。在工作者中我有一个公共方法:
void PushFrame(byte* data);
将数据推送到std :: stack成员变量,以便每次在那里推送新数据对象时,worker都可以访问它。
我不明白这种互动一般是怎么做的?我可以从调用者线程调用PushFrame()并传递参数吗?或者我是否必须以某种特殊方式访问worker中的方法?
答案 0 :(得分:2)
通常您使用 producer-consumer-queue 进行此类工作。
每当工作线程用尽工作时,wait()
在boost::condition_variable
上受到与保存工作线程数据的堆栈相同的boost::mutex
的保护(您可能需要)在这里使用队列来减少不公平工作安排的风险。)
只要将新数据插入堆栈,您的PushFrame()
函数就会在该条件变量上调用notify_one()
。这样,工作线程将真正睡眠(即OS调度程序可能不会给它任何时间片),直到实际完成工作为止。
这里最容易出错的是锁定保护堆栈和condition_variable的互斥锁。除了避免数据结构上的竞争之外,还需要注意condition_variable不会错过通知调用,因此可能会在实际有更多可用工作的情况下等待等待。
class Worker {
void PushFrame(byte* data)
{
boost::lock_guard<boost::mutex> lk(m_mutex);
// push the data
// ...
m_data_cond.notify_one();
}
void DoWork()
{
while(!done) {
boost::unique_lock<boost::mutex> lk(m_mutex);
// we need a loop here as wait() may return spuriously
while(is_out_of_work()) {
// wait() will release the mutex and suspend the thread
m_data_cond.wait(lk);
// upon returning from wait() the mutex will be locked again
}
// do work from the queue
// ...
}
}
boost::mutex m_mutex;
boost::condition_variable m_data_cond;
[...]
};