2017-04-12 94 views
1

我正在學習C++中的多線程並剛剛發現互斥鎖。我的代碼如下:C++意外的多線程行爲

#include "stdafx.h" 
#include <thread> 
#include <iostream> 
#include <string> 
#include <mutex> 
using namespace std; 

std::mutex mu; 

void shared_print(string msg, int i) { 
    std::lock_guard<std::mutex> guard(mu); 
    cout << msg << i << endl; 
} 

void function_1() { 
    for (int i = 0; i > -3; i--) 
     shared_print("Thread1: ", i); 
} 

int main() { 
    std::thread thread1(function_1); 

    for (int i = 0; i < 3; i++) 
     shared_print("Main: ", i); 

    thread1.join(); 
    return 0; 
} 

從我的理解中,互斥鎖一次只允許訪問一個資源。所以互斥量將被第一個調用它的線程鎖定(Thread1)。當main線程嘗試訪問互斥鎖時,它將被阻止,直到互斥鎖被解鎖爲Thread1。一旦cout執行後,它將被解除阻塞,其中main將被允許執行。

我希望得到的結果進行交錯的呼叫如Thread1, Main, Thread1, Main

然而,而是我得到標準輸出下面的結果。該模式仍然是任何迭代次數相同:

Thread1: 0 
Thread1: -1 
Thread1: -2 
Main: 0 
Main: 1 
Main: 2 
+0

爲什麼它會交錯?沒有您的代碼強制執行的命令。如果一個線程仍然有CPU時間,它可以獲得剛剛釋放的鎖。 – Arash

回答

2

首先認識到,執行的順序是不確定的,所以你得到了什麼是完全有效的 - 並且在下一次運行它的時候,你可能會得到完全不同的順序。

我增加迭代的次數每個線程運行32的是,在過去的幾個迭代是這樣的:

Thread1: -22 
Main: 22 
Thread1: -23 
Main: 23 
Main: 24 
Thread1: -24 
Main: 25 
Thread1: -25 
Main: 26 
Thread1: -26 
Main: 27 
Thread1: -27 
Thread1: -28 
Thread1: -29 
Main: 28 
Main: 29 
Main: 30 
Main: 31 
Thread1: -30 
Thread1: -31 

所以,有時我們得到交錯,其他時候我們得到短期運行(4在這種情況下是最長的)來自一個線程。其他時候,我運行它,我得到了完美的交錯,所以整個事件作爲線程1的一個輸出,然後是來自Main的一個輸出,然後重複。

底線:您的代碼按預期工作。