2017-04-12 21 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; 
} 

私の理解から、ミューテックスは、一度に単一のリソースへのアクセスを許可します。したがって、mutexはそれを呼び出す最初のスレッド(Thread1)によってロックされます。 mainスレッドがmutexへのアクセスを試みると、mutexのロックが解除されてからThread1までブロックされます。 mainが実行されると、ブロックされます。coutが実行されます。

私は結果がなど

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つのスレッドから来ています)。私はそれを実行した他の時間、私は完璧なインタリーブを持っているので、すべてが1つのスレッドからの出力として、メインから1つの出力が続いて繰り返して走った。

ボトムライン:あなたのコードは期待通りに動作しています。