通常,您使用生產者 - 消費者隊列進行此類工作。
每當工作線程耗盡的工作,他wait()
S的上由同一boost::mutex
的堆棧保持工作線程的數據保護的boost::condition_variable
(你可能想在這裏使用一個隊列,而不是減少風險不公平的工作安排)。現在
你PushFrame()
功能。只要把它插入新的數據到堆棧中的條件變量調用notify_one()
。這樣,工作者線程纔會真正進入睡眠狀態(即操作系統調度程序可能不會給它任何時間片),直到實際工作完成。
這裏最容易出錯的是鎖定互斥鎖,保護堆棧和condition_variable。除了避免數據結構上的競爭之外,還需要注意condition_variable不會錯過notify通知,因此在實際有更多工作可用時可能會停滯不前。
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;
[...]
};
notify_one是condition_variable的一部分。工人應該繼承嗎?你可以添加一個簡單的概念例子嗎?謝謝! –
condition_variable應該可能是您的Worker類的成員。在答案中增加了一個小代碼示例。 – ComicSansMS
@ComicSansMS我認爲'做從隊列工作'的評論應該在循環結束時(檢查工作後),否則隊列可能是空的。這可能會在首次運行DoWork()時發生(如果尚未發佈任何工作)或者有多個工作線程,並且另一個線程在循環結束時釋放鎖之後捕獲該互斥。 – rhashimoto