winapi 线程在消息传递工作之前需要一些时间来初始化?
我有一个按顺序创建线程的主程序: 然后线程B ThreadA(传递ThreadB的ID) 使用CreateThread函数。
线程 A 使用 PostThreadMessage 向线程 B 发送消息。 B 使用 GetMessage 获取消息。
我遇到的问题是 PostThreadMessage 在第一次被调用时随机阻塞并且永远不会返回,有时程序运行良好,有时我运行程序,它在第一个 postthreadmessage 处以 0 CPU 使用率阻塞。但是,如果我在第一个 PostThreadMessage 之前将 Sleep(10) 添加到 ThreadA,我似乎永远不会遇到这个问题。
我对线程和消息的时间安排缺少什么?
I have a main program that creates the threads in order:
ThreadB then
ThreadA (which is passed ThreadB's ID)
using the CreateThread function.
Thread A sends a message to Thread B using PostThreadMessage.
B gets the message using GetMessage.
The problem I am having is that PostThreadMessage blocks randomly the first time it is called and never returns, some times the program funs fine, other times I run the program and it blocks with 0 CPU usage at the first postthreadmessage. However if I add Sleep(10) to ThreadA before the first PostThreadMessage, I never seem to encouter this problem.
What am I missing about the timing of threads and messages?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在线程拥有消息队列之前,您无法向该线程发送消息。在该线程调用 GetMessage 或 PeekMessage 等函数之前,不会创建消息队列。 sleep 所做的就是将发送线程延迟足够长的时间,以便接收线程调用
GetMessage
并设置其消息队列。顺便说一句,我强烈建议不要使用
PostThreadMessage
因为消息可能会丢失。最好在接收线程上创建一个仅消息窗口(其父级为HWND_MESSAGE
)并向其发送消息。You cannot send a message to a thread until it has a message queue. Message queues are not created until that thread calls a function such as
GetMessage
orPeekMessage
. What your sleep does is delay the sending thread long enough that the receiving thread has calledGetMessage
and set up its message queue.Incidentally, I strongly recommend against using
PostThreadMessage
as the messages can get lost. It is better to create a message-only window (with a parent ofHWND_MESSAGE
) on the receiving thread and send messages to that instead.为了添加安东尼·威廉姆斯的正确答案,我用来处理这个问题的代码如下所示。我有一个类似于 MyThread 的类...
问题的关键是您最终不能依赖
Sleep
来保证工作线程得到充分初始化。另外,一般来说,在允许启动线程恢复之前,工作线程通常需要完成一些最少量的工作。因此,在创建线程之前创建一个事件对象,在主线程上等待它,并在初始化完成后在工作线程上向它发出信号。To add to Anthony Williams correct answer, the code I use to deal with this looks like. I have a class similar to MyThread...
The crux of the issue is you ultimately cannot rely on a
Sleep
to guarantee that the worker thread is sufficiently initialized. Plus, in general there is usually some mimimal amount of work a worker thread needs to have done before the launching thread should be allowed to resume. So create an event object before creating the thread, wait for it on the main thread and signal it on the worker thread once the initialization is done.