2009-07-06 5 views
1

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

試してみる手掛かりはありますか?私はRTOSベースのアプリケーションをシミュレートしているので、Windows固有のコードをあまりにも多く入れすぎることは望ましくありません。

EDIT -

もう一つの手掛かり - 私はすべてのセマフォのブロックを削除する場合(いくつかの既知の競合条件があるが)、メッセージは正常に動作。しかし、メッセージキューはスレッドブロッキングの影響を受けてはいけません。

編集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 

答えて

0

あなたがスレッドを作成した後のPeekMessageを呼び出しますが、これらのスレッドがメッセージをディスパッチしているフル、アクティブなメッセージ処理ループを持っています言及しますか? msdnさんのコメント:

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

唯一の要件は、PeekMessageと呼ばれるスレッドが1回であるということです。

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

+0

ありがとうございます - 私は、コードに既にスリープリトライ機能があると述べておきます。スレッドにはウィンドウオブジェクトが関連付けられていないので、従来のメッセージ処理ループはありません.MsgWaitForMultipleObjectsを使用しています.QS_ALLEVENTSマスクを使用しています。これはPostThreadMessageの後に戻ります。そこに何か間違ったものがあるのだろうかと思います。私は確認します – Jeff

+0

[MSDN](http://msdn.microsoft.com/en-us/library/ms644946%28v=vs.85%29.aspx)は、イベントを作成し、そのことをお勧めするようです – Casebash