在我的C++应用程序中,我有一个后台线程,它做一些工作,将结果放到一个堆分配的内存块中,并调用PostMessage将结果传递给主线程。
通常,当窗口接收到消息时,它会处理结果,然后在lParam指定的内存上执行delete。
但我担心窗口可能会在处理消息和删除内存之前退出。
PostMessage能以某种方式保证目标窗口有机会处理消息吗?
如果不是,有什么众所周知的技术可以知道窗口是否释放了内存,或者后台线程是否需要负责删除它?
发布于 2013-09-13 00:14:21
PostMessage肯定会被放在接收窗口的消息队列中。然而,不能保证窗口会在那里。到那时它可能已经被毁了。帮助确保消息到达那里的一种方法是创建自己的隐藏窗口(COM经常使用这种技术),并将其发送到其队列中。这样,您就可以控制隐藏窗口何时被销毁。我们在实时数据传输中使用这种方法已经有很多年了。
让后台线程删除内存不是一个好主意,而且可能会导致竞态情况,因为它不知道何时删除内存是可以的。最好是张贴到你自己的窗口,并在那里删除它,当你完成它。
发布于 2013-09-13 00:31:52
考虑UI线程的经典消息循环:
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}从其他线程发布的消息将被获取和分派,但其传递取决于目标窗口是否已成功创建(且尚未销毁)。如果您可以控制消息,可以考虑直接在消息循环中处理消息。然而,当存在另一个(嵌套的)消息循环时,事情可能会变得复杂,该循环可以作为处理某些Windows消息的结果而创建。模式对话框就是一个简单的例子,但一些更复杂的事情,如COM调用,也会导致嵌套的消息循环。
因此,您不应该依赖有保证的消息传递。考虑使用诸如队列或列表之类的全局数据结构(使用临界区防止同时访问)来对数据对象进行排队。然后,您仍然可以使用PostMessage发布消息,并在lParam中传递指向数据对象的指针,但在消息处理程序中,您需要在全局队列中定位对象,并处理(或丢弃)先前排队但由于某种原因未得到处理的对象。通常,当您的线程退出时(WM_QUIT消息到达上面的循环中),您也应该对队列中剩余的内容进行一些处理。
https://stackoverflow.com/questions/18769111
复制相似问题