Click here to Skip to main content
Licence CPOL
First Posted 1 May 2008
Views 12,997
Downloads 120
Bookmarked 16 times

Message Thread Using IoCompletionPort

By | 1 May 2008 | Article
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)

About the Author

My2Cents

Software Developer

United States United States

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Questioncan I use this over telnet to winCE ARMV4 device? PinmemberK.O.20:55 6 May '08  
AnswerRe: can I use this over telnet to winCE ARMV4 device? PinmemberMy2Cents7:34 19 May '08  
GeneralRe: can I use this over telnet to winCE ARMV4 device? PinmemberK.O.20:32 19 May '08  

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.

Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120517.1 | Last Updated 1 May 2008
Article Copyright 2008 by My2Cents
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid