2012-09-10 57 views
3

我正在設計一個異步記錄器類如下。但是,不知道我是否正確使用boost條件變量。任何人都可以評論這個嗎?這裏processLogEntry方法是一個線程函數,我在這裏使用boost。使用升壓條件變量

void LogWriter::stopThread() 
{ 
    mStop = true; 
    mCond.notify_one(); 
    mThread->join(); 
} 

void LogWriter::processLogEntry() 
{ 
    while(!mStop) 
    { 
     boost::mutex::scoped_lock lock(mMutex); 
     mCond.wait(lock); 
     while(!q.empty()) 
     { 
      // process begins 
     } 
    } 
} 

void LogWriter::addLogEntry() 
{ 
    boost::mutex::scoped_lock lock(mMutex); 
    // add it in the queue 
    mCond.notify_one(); 
} 
+0

您的代碼中的一個明顯問題是'mStop'遭受競爭條件,可以通過使用'atomic <>'變量修改它。另外請同時更新你的代碼,將日誌推送到隊列中(我猜?)'q',讓我們更好地理解你的問題。 – user2k5

+0

我正在爲mStop使用volatile bool。即使這樣會有問題? – user243655

+0

mStop不會遇到競爭條件,因爲它僅由stopThread修改,並且stopThread在返回之前等待線程完成。 –

回答

3

因爲已經指出的那樣,你必須要麼使mStop原子或保護與互斥鎖的所有其訪問。忘記volatile,這與您的目的無關。

此外,在等待條件變量時,即使沒有調用通知函數(即所謂的虛擬喚醒),也可能會返回對wait的調用。因此,撥打wait需要被警惕。

void LogWriter::stopThread() 
{ 
    { 
     boost::mutex::scoped_lock lock(mMutex); 
     mStop = true; 
     mCond.notify_one(); 
    } 
    mThread->join(); 

} 

void LogWriter::processLogEntry() 
{ 
    for(;;) { 
     boost::mutex::scoped_lock lock(mMutex); 
     // We wait as long as we're not told to stop and 
     // we don't have items to process 
     while(!mStop && q.empty()) mCond.wait(lock); 

     // Invariant: if we get here then 
     // mStop || !q.empty() holds 

     while(!q.empty()) 
     { 
      // process begins 
     } 

     if(mStop) return; 
    } 
} 
+0

感謝您的回覆。你能讓我知道如何讓mStop成爲原子嗎? boost是否具有某種數據類型? – user243655

+0

@ user243655我不知道可移植的C++ 03解決方案。 (IIRC有一個Boost.Atomic庫正在審查中。)所以你可能想檢查你的系統上有什麼可用的。 –