2012-07-02 36 views
3

我有一個工作線程處理工作項的隊列。工作項目現在可能無法處理,因此工作線程可能會將他們推回到隊列中。在兩種不同條件下的pthread同步

void* workerFunc(void* arg) { 
    WorkItem* item = NULL; 

    while(true) { 
     { 
      scoped_lock(&queueMutex); 
      while(workerRunning && workQueue.empty()) 
       pthread_cond_wait(&queueCondition, &queueMutex); 
      if(!workerRunning) 
       break; 

      item = workQueue.front(); 
      workQueue.pop(); 
     } 

     // process item, may take a while (therefore no lock here), 
     // may also be considered unprocessable 

     if(unprocessable) { 
      scoped_lock(&queueMutex); 
      workQueue.push(item); 
     } 
    } 
    return NULL; 
} 

現在我需要做到以下幾點:不時,我需要通過工作隊列進行掃描以刪除不再需要的(從入隊的工作項目在同一個線程)的項目。我無法爲此使用queueMutex,因爲我可能會錯過當前正在處理的項目,所以我需要一種方法來暫停整個處理線程,所有撤消的項目實際上都在隊列中(最好在右上角while循環)。

我想到了第二個bool變量(「paused」)與另一個互斥體和條件變量的組合,但接下來是工作人員正在等待queueCondition上的信號的特殊情況;實際上,pthread_cond_wait()調用將不得不解鎖/鎖定這兩個互斥鎖。

我想這個問題一定有一個簡單的解決方案,但我似乎無法想出它 - 我希望你們中的一些人能夠幫助我。

非常感謝。

+1

如果生產者(該線程也插入項目)將會從隊列中刪除不必要的項目 - 它應該獲取相同的互斥體('queueMutex') - 因爲它是修改隊列。處理器線程是否剛剛將一個項目從隊列中彈出並對其進行處理並不重要 - 如果未處理,則下一次生產者掃描隊列中的不必要項目時,它將選擇該項目。 – Nim

+0

爲什麼條件在隊列不空時等待? – jxh

+1

哦,這是一個錯字,我會修好它,對不起。 – Pontomedon

回答

4

基本上你需要在POSIX上模擬WinAPI的WaitForMultipleObjects()調用。與WinAPI一樣,POSIX沒有一個API來等待所有類型的事件/對象。使用pthread_cond_timedwaitclock_gettime。您可以參考此文件WaitFor API瞭解許多實施細節。

這裏有一些有趣的代碼(太多可以發佈在答案中,但可用),可以解決您的問題。

P.S.參考這個問題的討論:WaitForSingleObject and WaitForMultipleObjects equivalent in linux

+1

非常感謝,我會盡力 – Pontomedon

+0

不客氣。所以接受的答案:) –