2

我有一个关于 C++ 中的并发性(使用 Boost 线程)的菜鸟问题,我还没有找到明确的答案。我有一个在单独的线程中运行的工作人员类。我只在程序开始时初始化工作人员一次.这个工人是“懒惰的”,只有当它从调用线程接收到它时才进行一些数据编码。在工人中,我有一个公共方法:

void PushFrame(byte* data);

它将数据推送到 std::stack 成员变量,以便每次将新数据对象推送到那里时工作人员都可以访问它。

我不明白这种互动通常是如何进行的?我可以从调用者线程调用 PushFrame() 并传递参数吗?还是我必须以某种特殊方式访问工作人员中的方法?

4

1 回答 1

2

通常,您使用生产者-消费者队列来完成此类工作。

每当工作线程用完工作时,他wait()就在一个boost::condition_variable受保护boost::mutex的堆栈与保存工作线程数据的堆栈相同(您可能希望在此处使用队列来最大程度地减少不公平工作调度的风险)。

您的PushFrame()函数现在notify_one()在将新数据插入堆栈时调用该条件变量。这样,工作线程将真正休眠(即操作系统调度程序可能不会给它任何时间片),直到真正有工作要做。

这里最容易出错的是互斥锁的锁定,它同时保护了堆栈和 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;
 [...]
};
于 2013-05-21T12:59:27.817 回答