2012-06-08 98 views
0

我正在Linux上進行多線程C++ boost。boost :: mutex無法避免C++程序中的競爭條件?

即使我嘗試使用鎖,以下程序仍然存在競態條件。

結果是8或9或5。它不應該發生。

#include <iostream> 
#include <boost/bind.hpp> 
#include <boost/threadpool.hpp> 
#include <boost/thread/mutex.hpp> 
#include <boost/thread.hpp> 

boost::mutex myMutex ; 
int g = 0 ; 

void f() 
{ 

    //myMutex.lock(); 
    { 
      boost::mutex::scoped_lock lock(myMutex); 
      ++g; 
    } 
    //myMutex.unlock(); 
    return ; 
} 
const int threadnum = 10; 
int main() 
{ 
    boost::threadpool::fifo_pool tp(threadnum); 
    for (int i = 0 ; i < threadnum ; ++i) 
      tp.schedule(boost::bind(f)); 
    std::cout << g << std::endl ; 
    return 0 ; 
} 

任何幫助將不勝感激。

謝謝!

+4

不應該等待線程停止嗎? – mfontanini

+2

唯一可以防止競爭條件或死鎖的是**正確的設計**。沒有銀彈。 –

+1

我還會補充說,在主返回之前,任務**確實已經完成了**:它是超出範圍之前完成所有任務並且可以更改的默認關閉策略。只是他們沒有完成...... std :: cout ...執行。 –

回答

7

完成:

明白,任務只安排 執行是非常重要的。計劃立即返回,並且 沒有任何關於何時執行任務的保證以及處理將採取多長時間的處理 。

您安排10個任務,然後立即打印出結果了多達通過到達線時執行

的std ::法院克< <的std :: ENDL;

所以,當你的互斥量確保線程每次增加一個g值時,你不會等待它們打印結果之前完成。 修改代碼的一種方法是等待池中的所有任務完成:

boost::threadpool::fifo_pool tp(threadnum); 
for (int i = 0 ; i < threadnum ; ++i) 
     tp.schedule(boost::bind(f)); 
tp.wait(); //WAIT FOR TASKS TO EXECUTE 
std::cout << g << std::endl ; 
return 0 ; 
5

我不知道我在讀這個權利,但它看起來像你安排了一堆東西,會增加g,然後在g的內容上調用cout。你的互斥鎖可以防止計劃中的特效相互踩踏,但最終沒有任何事情會迫使cout等到它們全部完成。你需要某種讀/寫互斥體。