这是 Windows 特定问题。
根据微软文档,
系统为每个 GUI 线程维护一个系统消息队列和一个线程特定的消息队列。为了避免为非 GUI 线程创建消息队列的开销,所有线程最初创建时都没有消息队列。仅当线程第一次调用某个特定用户函数时,系统才会创建线程特定的消息队列;没有 GUI 函数调用会导致创建消息队列。
到目前为止,我相信所有线程最初都是在没有消息队列的情况下创建的。今天,我用 PostThreadMessageW 对此进行了测试,因为据说
如果指定线程没有消息队列,该函数将失败。
但是,PostThreadMessageW 在创建后始终为所有线程返回 1 (TRUE)。
DWORD dwThreadID = GetCurrentThreadId();
BOOL bResult = PostThreadMessageW(dwThreadID, WM_QUIT, 123, 456);
为什么会出现这种情况?
也许是对 GetCurrentThreadId() 的调用实际上创建了消息队列。 正如 @Damien_The_Unknowner 在他的评论中所说,“文档对于‘特定用户函数’的实际含义有点模糊。” 我想他可能正在做某事。
我遇到了一个非常相似的问题,因为我正在玩一个相当古老的论坛帖子中的一些代码:Codeguru:工作线程和主线程通信。 我试图理解为什么名为 hoodoo 的发帖者会回复他自己的帖子并进行更正;看起来他在 CreateThread() 之前添加了对 PeekMessage() 的调用,以保证调用线程(主线程)中的消息队列在创建工作线程之前创建。
我试图通过忽略他的修正并在 CreateThread() 和 GetMessage() 之间添加一个 Sleep(100) 来破坏他的代码(根据他的假设)。 这应该为新创建的工作线程提供足够的时间来尝试在主线程调用 GetMessage() 之前发送消息。
我发现这似乎没有什么区别;即使添加了睡眠命令,代码也始终运行良好,无需更正。 据我所知,添加额外的 PeekMessage 没有做任何有用的事情,并且主线程似乎总是从工作线程中获取用户消息。
我怀疑 CreateThread() 和/或 GetCurrentThreadId() 确实是符合文档中提到的这些“特定用户函数”的函数。
当然,如果您希望任何工作线程向引用的线程发布消息,则必须为其提供有效的线程 ID。 在你的例子中,你正在传递自己线程的线程ID,但我认为这并不重要 - 仅仅获取线程ID的行为就足以导致Windows在你尝试发布消息之前创建消息队列留言。