2016-12-21 11 views
2

私はマルチスレッドプログラミングに触れていません。私は簡単なテストプログラムを持っている:ミューテックスのロックとロック解除の時間差

#include <mutex> 
#include <thread> 
#include <iostream> 
int main(){ 
    std::mutex mtx; 
    std::thread t1([&](){ 
     while (true){ 
      mtx.lock(); 
      std::cout << 1 << "Hello" << "\n"; 
      mtx.unlock(); 
     } 
    }); 
    std::thread t2([&](){ 
     while (true){ 
      mtx.lock(); 
      std::cout << 2 << "Hello" << "\n"; 
      mtx.unlock(); 
     } 
    }); 
    t1.join(); 
    t2.join(); 
} 

は、これは非常に単純なプログラムであり、それはミューテックスが1でロックを解除し、その後に買収されたことを意味し、ランダムなパターンで「1Hello」と「2Hello」を印刷します他のいくつかのランダムなパターンで実行されます。

標準で動作が指定されていますか?つまり、実装がt1に固執しないことを保証しますか?もしそうでなければ、どうすればそれを避けることができますか?

+0

「t1」はミューテックスのロックを解除する必要はありません。ちょうどコードを読んでください!また、現代の*プリエンプティブ*マルチタスキングとそれがどのように機能するかを読む必要があるようです。 –

+0

私は標準がそれを保証しているとは思わないが、実際には、両方とも実行される。 – MikeMB

+0

私はちょうど得ることができないのであなたの質問(多分いくつかのプロンプトを追加する)を正確に明確にすることができます:( 質問はここで答えるために広いです+あなたがマルチスレッド\レース-condition \ dead-lock \ live-lockなどあなたはあなた自身の質問に答えてくれるでしょう(それはそこにありました:)) – LordTitiKaka

答えて

3

誰が実行されるのか保証するべきではありません。あるスレッドの優先度を他のスレッドの優先度よりも高く設定できる場合は、このコードを使用して最も優先度の高いスレッドのみが実行されることを保証することができます。

実際の問題は何ですか?問題は、このコードが最悪の場合でもマルチスレッドを使用することです。これはかなりの成果であり、運動であるため悪くはありません。それはスレッドを連続的に実行するように要求し、長いアクションを実行しながらロックし、次のループのロックを解除するだけなので、実際には並列性はなく、mutexのためのバトルしかありません。

どうすれば解決できますか?スレッドが何らかのバックグラウンドアクションを実行してから、スレッドが条件を待つか待機させるには、少なくともスレッドをしばらくスリープさせ、可能な限り独立したスレッドを実行させ、長いアクションを実行しながら他をブロックしないようにします。


編集(小明確化):このコードは最悪の方法でマルチスレッドを使用している間、それはそれを行う方法についてのきれい例です。

+0

はい、その完全なコードがクリティカルセクションであるプログラムは並列化されません...しかし、より一般的なケースでは、いくつかのスレッドが同じ仕事をしたり(例えばsleep)、mutexによって保護されている部分はほとんどありません。それは実際には同じです(そうではありませんか?)、OSが1に固執しない確率を変更しました。 – YiFei

+0

スケジューラはアクティブなスレッドに時間を与えます。そのため、十分なスレッドがスリープしている(タイムアウトまたは何らかの条件で待機している)場合、問題はありません。より多くのスレッドがより長い時間稼働している場合、スケジューラはあるスケジューリングを行い、異なるスレッドにタイムスライスを割り当てることができます(シングルコア、マルチコアはもう少し複雑です)。これはOSによって処理されます。 C++。 – stefaanv

関連する問題