問題タブ [condition-variable]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
io - ミューテックス、条件変数、またはI / Oを待機すると、スレッドは自動的にyield()されますか?
当たり前のように思えますが、これが保証されているかどうかを確認したかっただけです(Linuxの場合)。待機条件が満たされるまで、スレッドはスケジューリングから除外されていますか?または、スレッドがスケジュールされ、まだ待機中であることを確認し、yield()を再度実行して、リソースを浪費しますか?
私が尋ねている理由は、Xスレッドを実行していて、何らかの理由で一部のスレッドがブロックされている場合、ブロックされたスレッドが実行可能なスレッドの邪魔になるのでしょうか(同じ優先順位であると仮定して)?
c++ - C++11 スレッド: notify_all() または notify_one() しかないのに?
私のスレッドは、タイムラインと似ていないものを実装して、リンクされたリスト (オーバーラップ、したがってスレッド) として動作します。各条件変数は、リンク リスト内の次のスレッドのロックを解除します。
通知するものが 1 つしかない場合はnotify_all()
、またはを使用する必要がありますか?notify_one()
windows - デバッガーにWindowsスレッドを強制的にスリープから復帰させるにはどうすればよいですか?
デッドロックをデバッグしています。条件変数を待機しているスレッドをウェイクアップして、スリープ条件を再チェックするときにトレースできるようにします。条件変数でスリープすると、誤ったウェイクアップが発生する可能性があります。そのようなウェイクアップを強制するにはどうすればよいですか?
c# - Monitor.Pulse in C#は最適ではないようです:ロックスコープ内にある必要があります
ネタバレ注意:質問は最後のフレーズです。
C#では、条件変数を使用する従来のパターンは次のようになります。
およびその他のスレッド:
これは私のコードから抜粋した例です。パルスをロックスコープの外に置くと、コンパイルされません。ただし、これは正しい方法です。cf:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686903(v=vs.85).aspx および: http: //www.installsetupconfig.com/win32programming/threadprocesssynchronizationapis11_7.html ( "中身")
そして確かに、あなたがまだクリティカルセクションにいるときに眠っているスレッドに合図するのはばかげています。スリーピングスレッドは(すぐにではなく)ウェイクアップできないため、批判的なセクションの内側にもあるためです!
したがって、.NETまたはC#のPulse呼び出しが実際にはロックオブジェクトにフラグを立てているだけで、スコープ外になると、この時点で条件変数を実際に「パルス」することを願っています。そうしないと、最適性の問題が発生するためです。
では、なぜMonitorオブジェクトのデザインがそのように選択されたのでしょうか。
編集:
私はこの論文で答えを見つけました: http ://research.microsoft.com/pubs/64242/implementingcvs.pdf セクション「信号とブロードキャストの最適化」とNTカーネルに関する前のセクションとセマフォの上に条件変数を作成する方法、これが「ダーンドキュー」を導入する理由です。今ではそれが私をより良いエンジニアにします。
c++ - 生産者と消費者のシナリオでブースト条件変数を使用するにはどうすればよいですか?
編集:以下
バッファ内のデバイスからのデータのストリーミングを担当するスレッドが 1 つあります。さらに、そのデータに対して何らかの処理を行う N 個のスレッドがあります。私のセットアップでは、ストリーマー スレッドがデバイスからデータをフェッチし、新しいデータをフェッチするかタイムアウトに達する前に、N 個のスレッドが処理を完了するまで待機したいと考えています。N スレッドは、処理を続行する前に、新しいデータがフェッチされるまで待機する必要があります。このフレームワークは、バッファで N スレッドの処理を繰り返したくない場合、およびすべてのバッファをスキップせずに処理したい場合に機能するはずです。
注意深く読んだ後、条件変数が必要であることがわかりました。私はチュートリアルやその他のスタック オーバーフローの質問に従いました。これが私が持っているものです。
グローバル変数:
メンバー変数:
データ受信ループ (1 つのスレッドがこれを実行):
データ処理ループ (N 個のスレッドがこれを実行)
これら 2 つのループは、同じクラスの独自のメンバー関数にあります。変数 buffer はメンバー変数であるため、スレッド間で共有できます。
受信スレッドが最初に起動されます。data_ready 変数は、サイズ N の bool のベクトルです。data_ready[i] は、データを処理する準備ができている場合は true であり、スレッドがデータを既に処理している場合は false です。関数 any(data_ready) は、data_ready の要素のいずれかが true の場合に true を出力し、それ以外の場合は false を出力します。set_true(data_ready) 関数は、data_ready のすべての要素を true に設定します。受信側スレッドは、処理中のスレッドがまだ処理中かどうかを確認します。そうでない場合は、データをフェッチし、data_ready フラグを設定し、スレッドに通知し、処理が完了するまで最初に停止するループを続行します。処理スレッドは、それぞれの data_ready フラグが true であることを確認します。true になると、処理スレッドはいくつかの計算を行い、それぞれの data_ready フラグを 0 に設定して、ループを続行します。
処理スレッドが 1 つしかない場合、プログラムは正常に実行されます。スレッドを追加すると、処理の出力がガベージになるという問題が発生します。さらに、何らかの理由で処理スレッドの順序が重要になります。言い換えれば、私が起動した最後のスレッドは正しいデータを出力しますが、前のスレッドは、処理のための入力パラメーターが何であれ (有効なパラメーターを想定して) ガベージを出力します。問題の原因がスレッド コードにあるのか、デバイスまたはデータ処理の設定に問題があるのかはわかりません。処理ステップと受信ステップで couts を使用してみます。N 個の処理スレッドを使用すると、次のように出力が表示されます。
条件変数の使い方は正しいですか? 何が問題なのですか?
編集:フォークの提案に従い、コードを次のように変更しました。
データ受信ループ (1 つのスレッドがこれを実行):
データ処理ループ (N 個のスレッドがこれを実行)
それはいくぶんうまく機能します。正しいロックを使用していますか?
c++ - 条件変数を使用したリーダーライターロック
boostもtbbライブラリの条件変数にもリーダー/ライターロック(つまり、boostの共有ミューテックス)を操作するインターフェイスがないことがわかりました。condition_variable :: wait()はミューテックスロックのみを受け入れます。しかし、リーダーライターロックで動作させるのは非常に合理的だと思います。誰かがそれをサポートしない理由、または人々がそれをサポートしない理由を教えてもらえますか?
ありがとう、Cui
c++ - std::condition_variableスプリアスブロッキング
ご存知のように、条件変数は、誤ったウェイクアップを回避するためにサイクルで呼び出す必要があります。このような:
別のスレッドが待機中のスレッドをウェイクアップする場合は、条件フラグをtrueに設定する必要があります。例えば:
このシナリオで条件変数がブロックされる可能性はありますか?
1)待機中のスレッドは条件フラグをチェックし、それがFALSEに等しいことを検出したため、condvar.wait()
ルーチンに入ります。
2)ただし、この直前(ただし、条件フラグのチェック後)に、待機中のスレッドがカーネルによってプリエンプトされます(タイムスロットの有効期限などのため)。
3)このとき、別のスレッドが待機中のスレッドに状態を通知したいと考えています。条件フラグをTRUEに設定し、呼び出しますcondvar.notify_one();
4)カーネルスケジューラが最初のスレッドを再度実行すると、condvar.wait()
ルーチンに入りますが、通知はすでに欠落しています。
したがって、condvar.wait()
ウェイクアップ通知がなくなったため、条件フラグがTRUEに設定されていても、待機中のスレッドを終了することはできません。
出来ますか?
c++ - std::condition_variable::notify_one() が 2 回呼び出されました
次のように、時間間隔なしで std::condition_variable::notify_one() を 2 回呼び出した場合、待機しているスレッドの数がウェイクアップします。
これらの通知が同じスレッドに何度も配信されるのではなく、異なるスレッドに配信されるという保証はありますか?
c++ - std :: condition_variable :: notify_one()がコンテキストスイッチなしで数回呼び出されました
この例では、待機中のスレッドの数がウェイクアップします。
1番目のスレッド:
2番目のスレッド:
3番目のスレッド(2番目と同じ):
この例では、両方の通知が同じスレッドではなく、異なるスレッドに複数回配信されるという保証はありますか?
つまり、notify_one()の意味は次のとおりです。
(*) 注意を払う!ここでは、「待機中のスレッドが過去に通知され、ウェイクアップされ、いくつかの処理を実行して、再びcondvar.wait()に入った」というシナリオについては話していません。もちろん、この場合、いくつかのnotify_one()ルーチンがウェイクアップできます。同じスレッドを何度も繰り返します。
私は別のケースについて話している:
notify_one()は待機中のスレッドにウェイクアップについて通知しましたが、この待機中のスレッドがカーネルスケジューラからタイムスロットを受け取り、実行を継続する前に、別のnotify_one()が再度呼び出されました。この2番目の通知が、最初の通知からまだウェイクアップされていないときに、同じスレッドに再度配信される可能性はありますか?
c++ - C++11スレッドセーフキュー
私が取り組んでいるプロジェクトでは、複数のスレッドを使用してファイルのコレクションを処理しています。各スレッドは処理されるファイルのリストにファイルを追加できるので、私は(私が思っていたように)スレッドセーフなキューをまとめました。関連する部分は次のとおりです。
ただし、if (...wait_for(lock, timeout) == std::cv_status::no_timeout) { }
ブロック内でセグフォールトが発生することがあります。gdbで検査すると、キューが空であるためにセグフォールトが発生していることがわかります。これはどのように可能ですか?通知されたときにwait_for
のみ戻るというのが私の理解でした。これは、新しいアイテムをキューにプッシュした後にのみ発生するはずです。cv_status::no_timeout
FileQueue::enqueue