2013-10-02 36 views
4

我們有一個多線程應用程序。在當前的實現中,線程1在啓動時創建並定期(每秒左右,可配置)喚醒以檢查磁盤是否存在潛在的保存文件。這些文件由另一個線程保存,thread2。那運行線程1和它的週期性喚醒可能會減慢應用程序。將boost :: condition提升性能嗎?

現在我們有機會使用boost ::條件變量把線程1阻塞,直到線程2通知它。通過這樣做,需要創建一個標誌以避免從線程2不必要的通知,並且該標誌需要被同步並且通過線程2以高頻率(數百秒在幾秒內)被檢查。或線程1將在每次寫入時發出通知。

我的問題在這裏有以下幾種:

  1. 在升壓::條件的實現中,線程1仍然需要頻繁地醒來以檢查一個標誌和區別是實現從我們隱藏但它實際上是這樣做的。我對嗎? Windows和Java中的類似API可以做同樣的事情嗎?

  2. 即使線程未處於等待狀態,如果線程經常被多次通知,會發生什麼情況?

  3. 在我的情況下,它會通過切換到boost :: condition實現來提高整體性能?我的看法是第

+0

這取決於如何提高::條件實施。如果它使用系統條件變量,則thread1應該從調度中撤銷,直到通知爲止,直到通知後纔會喚醒。 – RedX

+0

您提到的標誌是在創建新文件時設置的,並且在thread1完成該文件時重置? – cpp

+0

是的。 thread2設置該標誌讓thread1知道文件已準備就緒。 thread1會處理它,然後重置該標誌。 – 5YrsLaterDBA

回答

1
  1. 在POSIX和Win32的boost ::條件是使用基於事件API來實現。從技術上來講,線程在獲得事件之前不會醒來。
  2. 如果線程在信號發送後進入等待狀態,信號將會丟失。您應該閱讀關於實施「生產者/消費者」的基於事件的模式和策略。您的文件寫入/讀取示例是經典的生產者/消費者實例。爲了避免丟失信號,請執行它類似於維基百科的C++ 11例如:http://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem#Example_in_C.2B.2B

的想法是,線程1永遠鎖定共享互斥體,如果它不等待條件:

//thread1 - consumer 
void thread1() { 
    boost::scoped_lock lock(sharedMutex); 
    // shared mutex locked, no events can be sent now 
    while(1) { 
     // check for files written by thread2 
     sharedCond.wait(lock); // this action unlocks the shared mutex, events can be sent now 
    } 
} 

//thread2 - producer 
void thread2() { 
    boost::scoped_lock lock(sharedMutex); // will wait here until thread 1 starts waiting 
    // write files 
    sharedCond.notify_one(); 
} 

3.性能問題:此更改不是關於性能,而是將輪詢更改爲事件模型。如果您的thread1每隔1秒醒來一次,切換到事件模型不會改善CPU或I/O負載(每隔1秒鐘無需文件驗證),直到您在嵌入式系統中運行,頻率爲幾KHz且I/O操作阻止整個過程。 它將改善thread1反應時間,在輪詢模式下,文件更改的最大響應時間爲1秒,切換到事件後將立即採取措施。 另一方面,在事件模型中thread2的性能可能會降低 - 在它沒有等待任何事情,並且它使用條件之前 - 它將不得不鎖定共享互斥體,這可能在thread1正在讀取文件時鎖定。

0

檢查高頻標誌正是boost :: condition允許您避免的。thread1()只是等待flag進行設置:

#include <mutex> 
#include <condition_variable> 
#include <thread> 

std::mutex mut; 
bool flag; 
std::condition_variable data_cond; 

void thread2() 
{ 
    //here, writing to a file 
    std::lock_guard<std::mutex> lk(mut); 
    flag = true; //a new file is saved 
    data_cond.notify_one(); 
} 

void thread1() 
{ 
    while(true) 
    { 
     std::unique_lock<std::mutex> lk(mut); 
     data_cond.wait(lk,[]{return flag;}); 
     //here, processing the file 
     flag = false; 
     lk.unlock(); 
    } 
} 

這是一個基於清單4_1在C++ 11代碼:C++ Concurrency in Action, Chapter 4 Synchronizing concurrent operations