2013-05-21 50 views
2

對於C++中的併發性(使用Boost線程),我還沒有找到明確的答案,我有一個關於併發的問題。我有一個工作類,它運行在一個單獨的線程中。我只在程序啓動時初始化worker。這個worker是「懶惰」的,只有當它從調用線程接收到時才進行一些數據編碼。在worker中我有一個公共方法:將數據從調用者線程傳遞到另一個boost :: thread中的方法

void PushFrame(byte* data); 

將數據推送到std :: stack成員變量,以便工作人員可以在每次將新數據對象推送到那裏時訪問它。

我不明白的是這樣的互動通常如何完成?我可以從調用者線程調用PushFrame()並傳遞參數嗎?還是我必須以某種特殊的方式訪問員工中的方法?

回答

2

通常,您使用生產者 - 消費者隊列進行此類工作。

每當工作線程耗盡的工作,他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; 
[...] 
}; 
+0

notify_one是condition_variable的一部分。工人應該繼承嗎?你可以添加一個簡單的概念例子嗎?謝謝! –

+1

condition_variable應該可能是您的Worker類的成員。在答案中增加了一個小代碼示例。 – ComicSansMS

+0

@ComicSansMS我認爲'做從隊列工作'的評論應該在循環結束時(檢查工作後),否則隊列可能是空的。這可能會在首次運行DoWork()時發生(如果尚未發佈任何工作)或者有多個工作線程,並且另一個線程在循環結束時釋放鎖之後捕獲該互斥。 – rhashimoto

相關問題