Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 邮递信息:保证送达吗?_C++_Windows - Fatal编程技术网

C++ 邮递信息:保证送达吗?

C++ 邮递信息:保证送达吗?,c++,windows,C++,Windows,在我的C++应用程序中,我有一个后台线程,它执行一些工作,把结果放入堆内存块中,并调用以将结果传递给主线程。 通常,当窗口接收到消息时,它会处理结果,然后对lParam指定的内存执行delete 但我担心窗口可能会在处理消息和删除内存之前退出 PostMessage是否以某种方式保证目标窗口将有机会处理消息? 如果没有,是否有已知的技术可以知道窗口是否释放了内存,或者后台线程是否需要负责删除它?PostMessage肯定会被放入接收窗口的消息队列中。然而,不能保证窗户会在那里。到那时它可能已经被

在我的C++应用程序中,我有一个后台线程,它执行一些工作,把结果放入堆内存块中,并调用以将结果传递给主线程。 通常,当窗口接收到消息时,它会处理结果,然后对
lParam
指定的内存执行
delete

但我担心窗口可能会在处理消息和删除内存之前退出

PostMessage
是否以某种方式保证目标窗口将有机会处理消息?

如果没有,是否有已知的技术可以知道窗口是否释放了内存,或者后台线程是否需要负责删除它?

PostMessage
肯定会被放入接收窗口的消息队列中。然而,不能保证窗户会在那里。到那时它可能已经被摧毁了。 帮助确保消息到达目的地的一种方法是创建自己的隐藏窗口(COM经常使用这种技术)并将其发布到队列中。这样你就可以控制隐藏的窗口何时被破坏。我们在实时数据传输中使用了这种方法多年


让后台线程删除内存是一个坏主意,可能会导致竞争条件,即它不知道何时可以删除。最好发布到您自己的窗口,并在完成后将其删除。

考虑UI线程的经典消息循环:

   MSG msg;
   while(GetMessage(&msg, NULL, 0, 0) > 0)
   {
     TranslateMessage(&msg);
     DispatchMessage(&msg);
   }
从另一个线程发布的消息将被获取和发送,但其传递取决于目标窗口是否已成功创建(尚未销毁)。如果您对消息进行控制,可以考虑在消息循环中直接处理消息。然而,当存在另一个(嵌套的)消息循环时,事情可能会变得复杂,这可能是处理某些Windows消息的结果。一个简单的例子是模式对话框,但一些更复杂的事情,如COM调用,也会导致嵌套的消息循环


因此,您不应该依赖于有保证的消息传递。考虑使用一个全局数据结构,如队列或列表(受关键段的同时访问保护)来对数据对象进行排队。然后,您仍然可以使用
PostMessage
发布消息,并在
lParam
中传递指向数据对象的指针,但在消息处理程序中,您需要在全局队列中找到对象,并处理(或丢弃)先前排队但由于某种原因尚未处理的对象。通常,当您的线程退出时(
WM_QUIT
message到达上面的循环中),您也应该对队列中剩余的内容进行一些处理。

线程竞争可能会在延迟发布消息传递之前破坏窗口,在这种情况下,没有地方发送消息。我没有发布对参数的“强引用”,而是将它们放在内部队列中,该队列在窗口销毁时刷新,或者从发布的消息处理程序中删除。请注意,消息可以从应用程序外部发布,因此它们的内容应被视为不受信任的输入。对于来自不可信来源的指针,您可以做什么?关于如何实际解决问题的极好建议。作为一个附带的好处,它可以防止粉碎攻击,因为您可以检测到实际上与队列项目不对应的指针。嗯,您的数据处理可能仍然会感到困惑,但您不会取消对野生指针的引用。而且,SList适合这种队列,并且避免了对关键部分的需要。