1

Windows Vista でマルチスレッド シミュレーションを実行しています。PostThreadMessage を使用してスレッド間でメッセージを送信すると、すべてのスレッドから PeekMessage を呼び出すため、スレッド ID が有効であり、スレッドにメッセージ キューがあることを (デバッガーをステップ実行して) 確信しているにもかかわらず、ERROR_INVALID_THREAD_ID を取得しています。 MSDNで指定されているように、それらを作成した後。ターゲット スレッドが中断されている可能性がありますが、私が知る限り、それは問題ではありません。

何を試すかについての手がかりはありますか?私は RTOS ベースのアプリケーションをシミュレートしているので、Windows 固有のコードをあまり追加する必要がないように願っています。

編集 -

別の手がかり - すべてのセマフォ ブロッキングを削除すると、メッセージは正常に機能します (ただし、既知の競合状態がいくつかあります)。しかし、メッセージ キューはスレッド ブロックの影響を受けるべきではありませんよね?

編集2 MSDNで提案されているように、コードには次の再試行メカニズムもあります。しかし、それでもうまくいきません - 再試行は常に失敗します。うーん.....

BOOL bResult = false;
int retry = 0;
DWORD dwError = 0;
do 
{
   bResult = PostThreadMessage(pTaskHandle->dwThreadID,0,0,(LPARAM)pMessage);
   if (!bResult)
   {
      dwError = GetLastError();
      retry++;    // should only happen once, if the dest thread has no msg queue
                  // the retry establishes the queue
      Sleep(500);
   }
} while (!bResult && retry<3); // MSDN says try this a few times to start msg queue
4

1 に答える 1

1

スレッドを作成した後に PeekMessage を呼び出すと述べていますが、これらのスレッドには、メッセージをディスパッチする完全でアクティブなメッセージ処理ループがありますか? msdn は次のように述べています。

PostThreadMessage を呼び出します。失敗した場合は、Sleep 関数を呼び出して、PostThreadMessage を再度呼び出します。PostThreadMessage が成功するまで繰り返します。

これは、スレッドが PeekMessage を 1 回呼び出すことだけが必要な場合は、少し間抜けに聞こえます。

経由で投稿されたメッセージにも注意してください。PostThreadMessage は DispatchMessage でディスパッチされません。メッセージを送信するためのウィンドウがないため、これは明らかなように思えますが、特に MsgWaitForMultipleObjects などを使用してハンドルを待機する場合に、人々がそれを行うのを見てきました。この場合、ERROR_INVALID_THREAD_ID を取得する可能性は低いと思われます...メッセージを見逃す可能性が高くなります。

于 2009-07-07T04:06:39.767 に答える