2017-10-17 49 views
2

mutexロックは、呼び出された順にスレッドに与えられますか? 3つのスレッドA、B、Cとmutex mtxがあるとします。 Aがmtx.lock()を最初に呼び出し、次にBとCを呼び出すと、Aが最初にロックを取得し、次にBとCが続くことを意味します。そうでない場合、どうすれば保証できますか?mutexロックの順序

+2

これは本物の質問です。 [mcve]はそれを_good_質問に変換します。 (注:私は、OPはスレッドAがスレッドBとCのロック順であることを確かに知っていると思います) – YSC

+0

"A"は最初にロックを取得しますが、 B "と" C " – AhmadWabbi

+0

は、BとCの順序を強制する方法はありますか? – Rishi

答えて

1

mutexで複数のスレッドが待機している場合は、待機中のスレッドが選択されます。先入れ先出し(FIFO)注文を想定しないでください。カーネルモードのAPCなどの外部イベントは、待機順を変更する可能性があります。 - MSDNから、Mutexオブジェクトについてのページ。

リンクを参照してください: Mutex Objects

+0

この場合、注文を保証するために何が使用できますか? – Rishi

+0

このリンクは、プラットフォーム固有のmutex APIに関するものと思われます。しかし、Askerが標準のC++以外のもの(すなわち、 'std :: mutex')を使用しているという表示はありません。 –

+0

現在の所有者がmutexのロックを解除したときに、どのスレッドがmutexの所有権を受け取るかは不定です(私はstd :: mutexを意味します) –

0

を私はロックを取得3つのタスク、印刷何かを作成し、参加されるのを待って終了し、これを実証するために簡単な例を持っています。バリア(3)を設定する代わりに、これを(2)に設定してtask_aを実行させ、他の2つがロックを争うようにすることができます。

私はboost :: barrierを使用して、作成されるとすぐに起動しないようにします。結果はFIFOではなく、非確定的な順序です。プラットフォームが異なると、異なる結果が得られます。 A demo of it in action

std::mutex foo; 
boost::barrier bar(3); 

void task_a() { 
    bar.wait(); 
    foo.lock(); 
    std::cout << "task a\n"; 
    foo.unlock(); 
} 

void task_b() { 
    bar.wait(); 
    foo.lock(); 
    std::cout << "task b\n"; 
    foo.unlock(); 
} 

void task_c() { 
    bar.wait(); 
    foo.lock(); 
    std::cout << "task c\n"; 
    foo.unlock(); 
} 

int main() 
{ 
    std::thread th1 (task_a); 
    std::thread th2 (task_b); 
    std::thread th3 (task_c); 
    th1.join(); 
    th2.join(); 
    th3.join(); 

    return 0; 
} 
+0

ありがとう。上記のコードでFIFOの順序をどのように保証しますか? – Rishi

+0

条件変数を使うことができます。条件変数は、あるスレッドが終了するともう一方のスレッドが終了するように指示します。 –

+0

私は条件変数が順序を保証しないと思った?またはコードを特定の方法で実装する必要がありますか?スレッドth2とth3はどちらもth1で待機する条件変数を使用していますが、th2は次の実行になることが保証されています – Rishi