2017-07-24 45 views
0

正如你看到的,當我刪除mt.lock()和mt.unlock,結果比50000什麼的線程競爭infulence?

爲什麼小了?居然會發生什麼?如果你能爲我解釋,我將非常感激。

#include <iostream> 
#include <thread> 
#include <vector> 
#include <mutex> 
using namespace std; 
class counter{ 
public: 
    mutex mt; 
    int value; 
public: 
    counter():value(0){} 
    void increase() 
    { 
     //mt.lock();                                           
     value++; 
     //mt.unlock(); 
    } 
}; 

int main() 
{ 
    counter c; 
    vector<thread> threads; 
    for(int i=0;i<5;++i){ 
     threads.push_back(thread([&]() 
           { 
            for(int i=0;i<10000;++i){ 
             c.increase(); 
            } 
           })); 
    } 
    for(auto& t:threads){ 
     t.join(); 
    } 
    cout << c.value <<endl; 
    return 0; 
} 

回答

0

++實際上是兩個操作。一個是閱讀價值,另一個是增加價值。由於它不是原子操作,所以在同一代碼區域中運行的多個線程會混淆起來。

作爲一個例子,考慮三個線程沒有任何鎖定在相同的區域內運行:

  1. 線程1和2讀value999
  2. 線程1計算遞增的值作爲1000和更新變量
  3. 線程3讀取1000,增量爲1001並更新變量
  4. 線程2將遞增值計算爲999 + 1 = 1000並覆蓋與1000

現在,如果你使用類似的"fetch-and-add"指令,這原子,你就不需要任何鎖3的工作。見fetch_add