我在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
答案 0 :(得分:1)
您提到在创建线程后调用PeekMessage但这些线程是否具有调度消息的完整,活动的消息处理循环? msdn说:
调用PostThreadMessage。如果失败,请调用Sleep函数并再次调用PostThreadMessage。重复,直到PostThreadMessage成功。
如果唯一的要求就是那个名为PeekMessage的线程一次,这听起来有点傻。
还要注意通过发布的消息。 PostThreadMessage不会在DispatchMessage中调度。这似乎是显而易见的,因为消息没有窗口,但我已经看到人们这样做,特别是当使用MsgWaitForMultipleObjects等等处理句柄时。在这种情况下,你似乎不太可能得到ERROR_INVALID_THREAD_ID ......更有可能你会错过这条消息。