5

マルチスレッド(2スレッド)プログラムでは、次のコードがあります。

while(-1)
{
    m.lock();

    (...)

    m.unlock();
}

mはミューテックスです(私の場合はc ++ 11std::mutexですが、別のライブラリを使用しても変更されないと思います)。

最初のスレッドがミューテックスを所有し、それが部分的に何かを行ったと仮定します(...)。2番目のスレッドはミューテックスを取得しようとしましたが、最初のスレッドがリリースされるのを待っていますm

問題は、スレッド1が(...)実行を終了してミューテックスのロックを解除したときに、スレッド2がミューテックスを取得するか、スレッド1がスレッド2の前にミューテックスを再取得できるかどうかを確認できるかlock()どうかです。

4

5 に答える 5

4

C ++標準は、ミューテックスへの順序ロックが許可されていることを保証するものではありません。したがって、アクティブなスレッドが、他のスレッドがロックを取得しようとせずに、ロックを取得し続ける可能性はunlock()十分にあります。C++標準がスレッドの優先順位を制御する方法を提供しているとは思いません。あなたが何をしようとしているのかわかりませんが、遭遇した問題を回避する別のアプローチがあるかもしれません。lock()std::mutex m

于 2012-12-21T22:22:31.080 に答える
3

両方のスレッドの優先度が等しい場合、標準のミューテックス実装によるそのような保証はありません。一部のOSには「待機中」のリストがあり、何かをリリースすると「最長待機」が選択されますが、これは実装の詳細であり、確実に信頼できるものではありません。

そして、2つのスレッドがあり、それぞれが次のようなものを実行していると想像してください。

m.lock();

(...)

m.unlock();
(...)    // Clearly not the same code as above (...)
m.lock();

(...)    // Some other code that needs locking against updates. 

m.unlock();

上記のコードで、毎回2番目のロックのスレッドを切り替えますか?

ちなみに、両方のスレッドがループ全体でロック付きで実行されている場合、ロックのポイントは何ですか?

于 2012-12-21T22:16:16.450 に答える
1

スレッドは相互に順序付けられていないため、保証はありません。実際、唯一の同期ポイントミューテックスロックです。

たとえば、関数をタイトループで実行している場合、最初のスレッドがすぐにロックを再取得する可能性は十分にあります。一般的な実装には、ミューテックスでスリープしているスレッドがある場合に通知とウェイクアップのメカニズムがありますが、コンテキストスイッチを実行するのではなく、実行中のスレッドを続行させるバイアスもある可能性があります...実装と詳細に依存します当時のプラットフォーム。

于 2012-12-21T22:25:23.487 に答える
1

C++または基盤となるOSによって提供される保証はありません。

ただし、クリティカル領域(この場合はミューテックス)へのスレッドの到着時間によって決定されるある程度の公平性があります。この公平性は統計的確率として表すことができますが、厳密な保証ではありません。ほとんどの場合、この選択はOS実行スケジューラに依存します。OS実行スケジューラは他の多くの要因も考慮します。

于 2012-12-22T00:02:35.080 に答える
-1

このようなコードに依存するのは得策ではないため、おそらく設計を変更する必要があります。ただし、一部のオペレーティングシステムでは、sleep(0)によってスレッドが生成されます。(WindowsではSleep(0))繰り返しますが、これに依存しないことをお勧めします。

于 2012-12-21T23:02:47.137 に答える