Multithreading 在线程之间使用SendMessageToDescendant
在我的MFC应用程序中,我有一个工作线程监听网络连接,当一些信息到达时,我调用Multithreading 在线程之间使用SendMessageToDescendant,multithreading,winapi,mfc,Multithreading,Winapi,Mfc,在我的MFC应用程序中,我有一个工作线程监听网络连接,当一些信息到达时,我调用sendMessageToDescendats通过lparam参数发送该信息。因此,每个帧窗口将获取消息,并可能通过WM\u SYNCHRONOTIFICATION消息的消息处理程序对其进行处理(WM\u SYNCHRONOTIFICATION是WM\u APP+x消息) 工作线程中的代码:(为简洁起见简化) 主线程中的消息处理程序: LRESULT CMyFrame::OnSynchroNotification(WP
sendMessageToDescendats
通过lparam参数发送该信息。因此,每个帧窗口将获取消息,并可能通过WM\u SYNCHRONOTIFICATION
消息的消息处理程序对其进行处理(WM\u SYNCHRONOTIFICATION
是WM\u APP+x
消息)
工作线程中的代码:(为简洁起见简化)
主线程中的消息处理程序:
LRESULT CMyFrame::OnSynchroNotification(WPARAM p1, LPARAM p2)
{
CNotificationMessage *pNotification = (CNotificationMessage*)p2;
// process message (ommited for brevity)
}
代码工作正常,但我不确定从
SendMessageToDescendants
返回时是否调用了所有OnSynchroNotification
。最简单的解决方案是使用计数器。在调用SendMessage
之前,将共享计数器初始化为您希望处理消息的子窗口数。然后,每个消息处理程序负责在完成其工作时递减计数器,并且事件循环可以在生成更多事件之前检查计数器是否为0。在伪C++中:
unsigned int sharedCount; // global/static shared value
while (TRUE)
{
CNotificationMessage notificationmessage;
Listen(¬ificationmessage); // blocking until some information arrives
unsigned int current = InterlockedCompareExchange(&sharedCount, activeWindowCount, 0);
if (current == 0)
{
m_pMainWnd->SendMessageToDescendants(WM_SYNCHRONOTIFICATION, NULL, (LPARAM)(newnotif));
}
else
{
// Still processing the last message.
}
while (InterlockedCompareExchange(&sharedCount, 0, 0) != 0)
{
Sleep(100);
}
}
LRESULT CMyFrame::OnSynchroNotification(WPARAM p1, LPARAM p2)
{
// Processing
InterlockedDecrement(&sharedCount);
}
while (TRUE)
{
CNotificationMessage notificationmessage;
Listen(¬ificationmessage); // blocking until some information arrives
m_pMainWnd->SendMessageToDescendants(WM_SYNCHRONOTIFICATION, NULL, (LPARAM)(newnotif));
DWORD waitResult = WaitForMultipleObjects(activeWindowCount, FrameEvents, TRUE, INFINITE);
if (waitResult == WAIT_OBJECT_0)
{
// Success
}
else if (waitResult == WAIT_FAILED)
{
// Failure: Use GetLastError() to figure out why the function call failed.
}
// Reset the events
}
LRESULT CMyFrame::OnSynchroNotification(WPARAM p1, LPARAM p2)
{
// Processing
SetEvent(thisFramesEvent);
}
稍微复杂一点的解决方案,但我个人更喜欢,因为您不必在等待完成时消耗CPU,就是为每个消息处理窗口创建一个事件,然后使用(或Ex版本)停止事件循环,直到完成。同样,在伪C++中:
unsigned int sharedCount; // global/static shared value
while (TRUE)
{
CNotificationMessage notificationmessage;
Listen(¬ificationmessage); // blocking until some information arrives
unsigned int current = InterlockedCompareExchange(&sharedCount, activeWindowCount, 0);
if (current == 0)
{
m_pMainWnd->SendMessageToDescendants(WM_SYNCHRONOTIFICATION, NULL, (LPARAM)(newnotif));
}
else
{
// Still processing the last message.
}
while (InterlockedCompareExchange(&sharedCount, 0, 0) != 0)
{
Sleep(100);
}
}
LRESULT CMyFrame::OnSynchroNotification(WPARAM p1, LPARAM p2)
{
// Processing
InterlockedDecrement(&sharedCount);
}
while (TRUE)
{
CNotificationMessage notificationmessage;
Listen(¬ificationmessage); // blocking until some information arrives
m_pMainWnd->SendMessageToDescendants(WM_SYNCHRONOTIFICATION, NULL, (LPARAM)(newnotif));
DWORD waitResult = WaitForMultipleObjects(activeWindowCount, FrameEvents, TRUE, INFINITE);
if (waitResult == WAIT_OBJECT_0)
{
// Success
}
else if (waitResult == WAIT_FAILED)
{
// Failure: Use GetLastError() to figure out why the function call failed.
}
// Reset the events
}
LRESULT CMyFrame::OnSynchroNotification(WPARAM p1, LPARAM p2)
{
// Processing
SetEvent(thisFramesEvent);
}
本例使用无限超时,但您始终可以设置合理的超时,并检查返回值WAIT\u timeout
,查看时间是否已过
(必需的免责声明:为了简洁易读,错误检查和变量初始化已从这两个版本中删除。有关如何检查错误的信息,请参阅文档。)。