ホームページ > バックエンド開発 > C++ > ブロッキング待機で StaTaskScheduler を使用する場合、STA スレッドでのデッドロックをどのように防ぐことができますか?

ブロッキング待機で StaTaskScheduler を使用する場合、STA スレッドでのデッドロックをどのように防ぐことができますか?

Barbara Streisand
リリース: 2025-01-11 11:08:42
オリジナル
787 人が閲覧しました

How Can Deadlocks Be Prevented on STA Threads When Using StaTaskScheduler with Blocking Waits?

StaTaskScheduler と STA スレッドのメッセージ ポンピング

Parallel チームの ParallelExtensionsExtras の StaTaskScheduler は、サードパーティが提供する従来の STA COM オブジェクトをホストするように設計されています。実装の説明には、MTA スレッドと STA スレッドをサポートし、WaitHandle.WaitAll などの基礎となる API の違いを処理すると記載されています。

ただし、STA スレッドでのデッドロックを防ぐために、StaTaskScheduler がメッセージを送信する待機 API (CoWaitForMultipleHandles など) を使用すると考えるのは誤りです。 TPL のブロック部分がメッセージを送出できない場合があり、デッドロックが発生します。

単純化したシナリオでは、インプロセス STA COM オブジェクト A がアウトプロセス オブジェクト B を呼び出し、B からのコールバックを取得することを期待しているときに問題が発生します。 BlockingCollection 内のどこかでブロッキング待機 (メッセージのポンピングではない) が発生しているため、 a.Method(b) への呼び出しは返されません。

解決策は、CoWaitForMultipleHandles を使用してメッセージを明示的にポンプするカスタム同期コンテキストを実装し、StaTaskScheduler によって開始されるすべての STA スレッドにインストールすることです。

MsgWaitForMultipleObjectsEx は、CoWaitForMultipleHandles よりもメッセージ ポンピングに適しています。カスタム同期コンテキストの Wait メソッドは、SynchronizationContext.WaitHelper へのフォワーダーとして実装することも、完全に機能するメッセージ ポンピング ループを含めることもできます。

次のコードは、メッセージ ポンピング ループを含むカスタム同期コンテキストの実装を示しています。

<code class="language-c#">// 核心循环
var msg = new NativeMethods.MSG();
while (true)
{
    // 带有 MWMO_INPUTAVAILABLE 的 MsgWaitForMultipleObjectsEx 返回,
    // 即使消息队列中已经看到但未删除消息
    nativeResult = NativeMethods.MsgWaitForMultipleObjectsEx(
        count, waitHandles,
        (uint)remainingTimeout,
        QS_MASK,
        NativeMethods.MWMO_INPUTAVAILABLE);

    if (IsNativeWaitSuccessful(count, nativeResult, out managedResult) || WaitHandle.WaitTimeout == managedResult)
        return managedResult;

    // 有消息,泵送并分派它
    if (NativeMethods.PeekMessage(out msg, IntPtr.Zero, 0, 0, NativeMethods.PM_REMOVE))
    {
        NativeMethods.TranslateMessage(ref msg);
        NativeMethods.DispatchMessage(ref msg);
    }
    if (hasTimedOut())
        return WaitHandle.WaitTimeout;
}</code>
ログイン後にコピー
このカスタム同期コンテキストとメッセージ ポンピング ループを使用すると、STA スレッドでブロッキング待機を使用している場合でもメッセージが確実にポンピングされ、STA スレッドのデッドロックが防止されます。

以上がブロッキング待機で StaTaskScheduler を使用する場合、STA スレッドでのデッドロックをどのように防ぐことができますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート