スレッドハンドルまたはスレッドIDがあると仮定して、C ++のコンテキストスイッチを特定のスレッドに強制する方法はありますか?
6 に答える
Windowsスレッドスケジューラに特定のスレッドを選択するように促すことしかできず、強制することはできません。最初に、同期オブジェクトでスレッドブロックを作成し、それを通知することによってこれを行います。その優先順位を上げることによって二次。
明示的なコンテキスト切り替えがサポートされているため、ファイバーを使用する必要があります。SwitchToFiber()を確認します。ファイバーはロングショットではスレッドではなく、古いコルーチンに似ています。ファイバーの全盛期は過ぎ去りました、彼らはもはやスレッドと競争していません。それらは非常にくだらないCPUキャッシュの局所性を持っており、複数のコアを利用することはできません。
いいえ、オペレーティングシステムに必要なスレッドを強制的に実行させることはできません。yield
ただし、コンテキストスイッチを強制するために使用できます...
yield
Win32APIでは関数SwitchToThread
です。実行可能なスレッドが他にない場合は、ゼロ値が返され、現在のスレッドは実行を継続します。
特定のスレッドを強制的に実行する唯一の方法は、プロセス/スレッドアフィニティを使用することですが、これが合理的な解決策である問題が発生することは想像できません。
コンテキストスイッチを強制する唯一の方法は、アフィニティを使用してスレッドを別のプロセッサに強制することです。
言い換えれば、あなたがやろうとしていることは実際には実行可能ではありません。
SwitchToThread()
このプロセッサで実行できる別のスレッドを実行する準備ができている場合、呼び出すとコンテキストスイッチが発生します。ドキュメントには次のように記載されています。
SwitchToThread関数を呼び出すと、オペレーティングシステムが実行を別のスレッドに切り替える場合、戻り値はゼロ以外になります。
実行する準備ができているスレッドが他にない場合、オペレーティングシステムは実行を別のスレッドに切り替えず、戻り値はゼロになります。
Sleep(0)
呼び出しでループしている間、他のスレッドの優先順位を一時的に上げることができます。これにより、制御が他のスレッドに渡されます。他のスレッドがlock
変数を増やし、それが再びゼロになるまで待つ必要があるとします。
// Wait until other thread releases lock
SetThreadPriority(otherThread, THREAD_PRIORITY_HIGHER);
while (InterlockedRead(&lock) != 0)
Sleep(0);
SetThreadPriority(otherThread, THREAD_PRIORITY_NORMAL);
Windows用の並行プログラミングという本をチェックします。スケジューラーは注目に値するいくつかのことをしているようです。
Sleep(0)は、優先度の高いスレッド(または同じ優先度の他のスレッド)にのみ譲ります。つまり、他の優先度の低いスレッドを実行する必要があるSleep(0)だけでは、優先度の逆転の状況を修正することはできません。SwitchToThreadを使用するか、ゼロ以外の期間スリープするか、一部のカーネルHANDLEで完全にブロックする必要があります。
2つの同期オブジェクト(2つのイベントなど)を作成し、 APISignalObjectAndWaitを使用できます。
がhObjectToWaitOn
シグナリングされておらず、他のスレッドがを待機しているhObjectToSignal
場合、OSは理論的には、タイムスライスが終了する前に、このAPI内でクイックコンテキストスイッチを実行できます。
また、現在のスレッドを自動的に再開する場合は、に小さな値(50や100など)を通知するだけdwMilliseconds
です。