Click here to Skip to main content
11,409,766 members (55,658 online)
Click here to Skip to main content

Message Thread Using IoCompletionPort

, 1 May 2008 CPOL
Rate this:
Please Sign up or sign in to vote.
Thread communication made easy!

Introduction

Windows has a simplified built-in mechanism for communication among threads, using message loops. APIs such as GetMessage(), PeekMessage() can be used to achieve this. E.g.,

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

Once the loop is setup, use PostThreadMessage() to send the message across. E.g.,

PostThreadMessage(
    nThreadId,
    nMsg,
    wParam,
    lParam);

In fact, message based communication is the building block of Windows. Of course, it has serious security implications as the source of the message is not known to the receiver, but that's a topic for another article.

In this article, I used this concept and the MFC macro style message handler declaration and wrapped them in a class that lets you send messages in two different modes:

  • PostMessage
  • SendMessage with timeout

The Code

In order to construct the message loop, I used CreateIoCompletionPort(), GetQueuedCompletionStatus() instead of the above mentioned method. The reasons for this are as follows:

  • IoCompletionPorts are fast and less resource intensive.
  • No restriction as in the other methods where the thread needs to belong to the same desktop, etc.

OK, let's see an example. By the way, the attached files have a Visual Studio based project that you can compile and run. Check the DemoThread class.

First, derive a class from 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
)
{
}

Elsewhere in your code:

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

And that's it. Just be careful; if you use SendMessage, you might end up in a deadlock if you haven't designed things properly.

Just include MsgHandler.[h,cpp] and MsgThread.[h,cpp] in your project. I hope you find it useful. Any comments or suggestions are most welcome.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

My2Cents
Software Developer
United States United States
No Biography provided

Comments and Discussions

 
Questioncan I use this over telnet to winCE ARMV4 device? PinmemberK.O.6-May-08 21:55 
AnswerRe: can I use this over telnet to winCE ARMV4 device? PinmemberMy2Cents19-May-08 8:34 
GeneralRe: can I use this over telnet to winCE ARMV4 device? PinmemberK.O.19-May-08 21:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150414.5 | Last Updated 1 May 2008
Article Copyright 2008 by My2Cents
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid