1

我有一个在 Windows Vista 上运行的多线程模拟。当我使用 PostThreadMessage 在线程之间发送消息时,我得到 ERROR_INVALID_THREAD_ID,即使我非常确定(通过调试器)线程 ID 是有效的,并且线程有一个消息队列,因为我从每个线程调用 PeekMessage在我创建它们之后,如 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 一次,这听起来有点傻。

另请注意,通过发布的消息。PostThreadMessage 不会在 DispatchMessage 中分派。这似乎很明显,因为没有消息可以发送到窗口,但我见过人们这样做,尤其是在使用 MsgWaitForMultipleObjects 等等待句柄时。在这种情况下,您似乎不太可能收到 ERROR_INVALID_THREAD_ID... 更有可能您只是错过了该消息。

于 2009-07-07T04:06:39.767 回答