Click here to Skip to main content
15,893,486 members
Articles / Programming Languages / C
Article

Message Thread Using IoCompletionPort

Rate me:
Please Sign up or sign in to vote.
3.11/5 (6 votes)
1 May 2008CPOL1 min read 28.6K   318   19   3
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.,

C++
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.,

C++
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:

C++
// 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:

C++
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)


Written By
Software Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questioncan I use this over telnet to winCE ARMV4 device? Pin
some1One16-May-08 20:55
some1One16-May-08 20:55 
AnswerRe: can I use this over telnet to winCE ARMV4 device? Pin
My2Cents19-May-08 7:34
My2Cents19-May-08 7:34 
GeneralRe: can I use this over telnet to winCE ARMV4 device? Pin
some1One119-May-08 20:32
some1One119-May-08 20:32 

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

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