65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 IoCompletionPort 的消息线程

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.11/5 (6投票s)

2008年5月1日

CPOL

1分钟阅读

viewsIcon

29247

downloadIcon

336

线程通信变得容易!

引言

Windows 具有一个简化的内置机制,用于线程间的通信,使用消息循环。可以使用诸如 GetMessage()PeekMessage() 之类的 API 实现此目的。例如:

MSG msg;
PeekMessage(
    &msg,
    NULL,
    0,
    0,
    PM_NOREMOVE);
while (true)
{
    BOOL bRet = GetMessage(
            &msg,
            NULL,
            0,
            0);
}

一旦设置了循环,使用 PostThreadMessage() 发送消息。例如:

PostThreadMessage(
    nThreadId,
    nMsg,
    wParam,
    lParam);

事实上,基于消息的通信是 Windows 的构建基础。当然,它存在严重的安全性隐患,因为接收者不知道消息的来源,但这又是另一个话题了。

在本文中,我使用了这个概念以及 MFC 宏风格的消息处理程序声明,并将它们封装在一个类中,该类允许您以两种不同的模式发送消息

  • PostMessage
  • SendMessage 带超时

代码

为了构建消息循环,我使用了 CreateIoCompletionPort()GetQueuedCompletionStatus(),而不是上述方法。原因如下:

  • IoCompletionPorts 速度更快,资源消耗更少。
  • 没有像其他方法那样的限制,例如线程需要属于同一个桌面等。

好的,我们来看一个例子。顺便说一下,附件中包含一个基于 Visual Studio 的项目,您可以编译并运行它。请查看 DemoThread 类。

首先,从 MsgThread 类派生一个类

// DemoThread.h
class DemoThread : public MsgThread
{
    DECLARE_MSG_MAP();
private:
    void OnMsgGoGetPizza(
        WPARAM wParam,
        LPARAM lParam);
};
// DemoThread.cpp
BEGIN_MSG_MAP(DemoThread, MsgThread)
    ON_MSG(kMsgGoGetPizza, OnMsgGoGetPizza ) 
END_MSG_MAP()
void
DemoThread::OnMsgGoGetPizza
(
    WPARAM wParam,
    LPARAM lParam
)
{
}

在您的代码的其他地方

DemoThread rThread1;
rThread1.Start();
rThread1.PostMessage(
    kMsgGoGetPizza,
    (WPARAM) 5,
    0);
rThread1.Stop();

就这样了。请小心;如果您使用 SendMessage,如果没有正确设计,可能会陷入死锁。

只需将 MsgHandler.[h,cpp]MsgThread.[h,cpp] 包含在您的项目中即可。希望对您有所帮助。欢迎提出任何意见或建议。

使用 IoCompletionPort 的消息线程 - CodeProject - 代码之家
© . All rights reserved.