C++ 来自目标线程的PostThreadMessage
今天,我看到了如下代码:C++ 来自目标线程的PostThreadMessage,c++,windows,multithreading,C++,Windows,Multithreading,今天,我看到了如下代码: void Foo() { MyMsgStruct myMsg; /* omission for simplicity */ /* send to update thread */ PostThreadMessage(myThreadId, myMessage, (WPARAM)myMsg, NULL); } 当从与myThreadId相同的线程调用Foo()时会发生什么情况,即从假定为目标线程的同一线程调用?这是一个性能问题还是仅仅
void Foo()
{
MyMsgStruct myMsg;
/* omission for simplicity */
/* send to update thread */
PostThreadMessage(myThreadId, myMessage, (WPARAM)myMsg, NULL);
}
当从与myThreadId
相同的线程调用Foo()
时会发生什么情况,即从假定为目标线程的同一线程调用?这是一个性能问题还是仅仅是写得不好的代码,或者两者兼而有之
我相信这可能会影响性能,因为我相信它会将消息排队到线程的队列,而不仅仅是执行它应该执行的操作,因此会稍微降低程序的速度
线程安全不是我关心的问题,无论哪个线程正在调用
PostThreadMessage()
,消息都会进入目标线程ID的消息队列。线程向自身发布消息是完全有效的。当线程为新消息抽取其消息队列时,将处理该消息。有时候,一个线程可能真的希望有一个延迟的操作,所以发布消息是好的。如果线程想要立即执行某项操作,那么调用PostThreadMessage()
没有任何意义,只需直接执行该操作即可。对于线程消息,没有与SendMessage()
等价的消息。无论哪个线程正在调用PostThreadMessage()
,消息都会进入目标线程ID的消息队列。线程向自身发布消息是完全有效的。当线程为新消息抽取其消息队列时,将处理该消息。有时候,一个线程可能真的希望有一个延迟的操作,所以发布消息是好的。如果线程想要立即执行某项操作,那么调用PostThreadMessage()
没有任何意义,只需直接执行该操作即可。对于线程消息,没有与SendMessage()
等效的消息。没有什么特别的,只是需要一段时间才能调用应该运行的代码。只是一个延迟,它不一定会让你的程序变慢。有时,您是故意这样做的,比如想要回复Windows消息,但立即这样做会导致重新进入问题
然而,应该尽量避免使用PostThreadMessage。当线程也创建窗口时,会发生非常糟糕的事情,几乎总是这样,因为您倾向于向UI线程发布代码,例如更新窗口。每当进入模式循环时,消息都会落在位存储桶中。与用于调整窗口大小的窗口类似。或显示MessageBox。总是倾向于在窗口中发布消息,这样消息就不会丢失。请检查PostMessage()的返回值
创建一个虚拟的不可见窗口,其窗口过程处理这些消息通常是一个好主意。您现在还可以检查是否需要post或是否可以直接使用SendMessage执行。比较GetWindowThreadProcessId和GetCurrentThreadId。没什么特别的,只是需要一段时间才能调用应该运行的代码。只是一个延迟,它不一定会让你的程序变慢。有时,您是故意这样做的,比如想要回复Windows消息,但立即这样做会导致重新进入问题 然而,应该尽量避免使用PostThreadMessage。当线程也创建窗口时,会发生非常糟糕的事情,几乎总是这样,因为您倾向于向UI线程发布代码,例如更新窗口。每当进入模式循环时,消息都会落在位存储桶中。与用于调整窗口大小的窗口类似。或显示MessageBox。总是倾向于在窗口中发布消息,这样消息就不会丢失。请检查PostMessage()的返回值
创建一个虚拟的不可见窗口,其窗口过程处理这些消息通常是一个好主意。您现在还可以检查是否需要post或是否可以直接使用SendMessage执行。比较GetWindowThreadProcessId和GetCurrentThreadId。这里有一些关于PostThreadMessage的进一步背景信息:旁注:发布引用自动变量(如
myMsg
)的消息时要小心,除非它是标量整数变量,并且是通过wParam
中的值传递的,在收件人线程能够检索和处理消息之前,自动变量可能会被销毁。当发布到同一线程时尤其如此,因为在Foo()
返回并且myMsg
被销毁之前不会发生任何消息处理(除非存在消息泵循环,但此处未显示)。堆分配解决了这个问题。这里有一些关于PostThreadMessage的进一步背景信息:旁注:发布引用自动变量(如myMsg
)的消息时要小心,除非它是一个标量整型变量,并且在wParam
中按值传递,在收件人线程能够检索和处理消息之前,自动变量可能会被销毁。当发布到同一线程时尤其如此,因为在Foo()
返回并且myMsg
被销毁之前不会发生任何消息处理(除非存在消息泵循环,但此处未显示)。堆分配解决了这个问题。只有一个窗口,线程是工作线程,因此UI线程没有危险。我读过很多关于PostThreadMessage()
和windows的问题,是的,它会产生比它解决的问题更多的问题。不,一个窗口就足以导致这个问题。不要这样做。如果你不想创建隐藏的窗口,那么就使用这个窗口。只有一个窗口,线程是工作线程,因此UI线程没有危险。我读过很多关于PostThreadMessage()
和windows的问题,是的,它会产生比它解决的问题更多的问题。不,一个窗口就足以导致这个问题。不要这样做。如果你不想创建隐藏的窗口,那么只需使用一个风