2017-06-14 36 views
0

爲什麼我的代碼中沒有任何競爭條件? 由於源這裏:http://en.cppreference.com/w/cpp/memory/shared_ptrshared_ptr中的競爭條件不會發生

如果執行訪問多個線程相同的shared_ptr不同步和任何這些訪問的使用的shared_ptr的非const成員函數然後將出現數據爭用;

class base 
{ 
public: 
    std::string val1; 
}; 

class der : public base 
{ 
public: 
    std::string val2; 
    int val3; 
    char val4; 
}; 

int main() 
{ 
    std::mutex mm; 
    std::shared_ptr<der> ms(new der()); 

    std::thread t1 = std::thread([ms, &mm]() { 
     while (1) 
     { 
     //std::lock_guard<std::mutex> lock(mm); 

      std::string some1 = ms->val2; 
      int some2 = ms->val3; 
      char some3 = ms->val4; 
      ms->val2 = "1232324"; 
      ms->val3 = 1232324; 
      ms->val4 = '1'; 
     } 
    }); 

    std::thread t2 = std::thread([ms, &mm]() { 
     while (1) 
     { 
      //std::lock_guard<std::mutex> lock(mm); 

      std::string some1 = ms->val2; 
      int some2 = ms->val3; 
      char some3 = ms->val4; 
      ms->val2 = "123435"; 
      ms->val3 = 123435; 
      ms->val4 = '3'; 
     } 
    }); 

    std::shared_ptr<base> bms = ms; 
    std::thread t3 = std::thread([bms]() { 
     while (1) 
     { 
      bms->val1 = 434; 
     } 
    }); 

    while (1) 
    { 
     std::this_thread::sleep_for(std::chrono::milliseconds(1)); 
    } 
} 
+1

代碼中存在數據競爭。編譯器不會給你一個錯誤,但它只是產生未定義的代碼。 – NathanOliver

+0

你有數據競賽**和**比賽條件,它們是不同的。然而,在你的例子中'shared_ptr'沒有,它全部在'der' –

+0

@Passer By上,但是那裏'std :: shared_ptr'的'operator->'可能有競爭條件。據我所知,爲了避免它,我應該使用'std :: atomic_load'並獲取'std :: shated_ptr'的副本以在另一個'std :: thread'中使用。 –

回答

3

數據競爭不會產生編譯失敗;他們產生未定義的行爲。該行爲可能是「正常工作」。或者「似乎工作正常,但巧妙地在12分鐘後打破某些東西」。或者「立即失敗」。

只是因爲代碼出現工作並不意味着它實際上。對於線程代碼,這比其他任何類型更爲真實。

0

我會建議你使用valgrind tool - helgrind。 調試多線程程序時,很難找到競爭條件。 要運行此工具,您需要在您的計算機上使用valgrind並運行它:

valgrind --tool=helgrind ./Your_Complied_File arg1 arg2 ...