Using PostThreadMessage to send messages to worker threads

Source: Internet
Author: User
Tags error code getmessage message queue sprintf

After reading the messages sent between windows threads carefully, I feel that my previous understanding is not profound. Talk about the understanding of PostThreadMessage.

 

PostThreadMessage is a thread body that sends a message to the specified thread ID. Its prototype is as follows:

 

BOOL PostThreadMessage(

                    DWORD idThread,

                    UINT Msg,

                    WPARAM wParam,

                    LPARAM lParam

);

       This function can either send a message to the worker thread or to the UI thread. The thread receiving PostThreadMessage must already have a message queue, otherwise the call to PostThreadMessage will fail. For this reason, using GetLastError will get an error code of 1444. This situation often occurs. There are two solutions:

 

1. Call PostThreadMessage, if it fails, Sleep will call PostThreadMessage again for a period of time until the call succeeds;

 

2. Create an Event object, let PostThreadMessage wait for the thread to create a message queue. You can force the system to create a message queue by calling PeekMessage. The sample code is as follows:

 

 

 

Assuming that mainAPP is the sending thread ThreadA is the receiving thread

 

/*mainAPP.cpp*/

...

hStartEvent = ::CreateEvent(0,FALSE,FALSE,0); //create thread start event

if(hStartEvent == 0)

{

          printf("create start event failed,errno:%d/n",::GetLastError());

          return 1;

}

::WaitForSingleObject(hStartEvent,INFINITE);

CloseHandle(hStartEvent);

if(!PostThreadMessage(threadaID, WM_MESSAGE_A,0,0))

{

          _tprintf(_T("post error! %d/n"), GetLastError());

          return 1;

}

...

ThreadA is the accepting thread

 

/* ThreadA */

MSG msg;

PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);

if(!SetEvent(hStartEvent))

{

          printf("set event error,%d/n",GetLastError());

          return 1;

}

while(true){

          if(GetMessage(&msg, 0,0,0)) {

                    switch(msg.message){

                              case WM_MESSAGE_A:

                               ...

                               break;

                              }

                    }

          }

}

If the message passed by PostThreadMessage contains information, pay attention to releasing the information in the message at the end. The method of attaching information to the message is as follows

 

/*The structure information is as follows*/

char* pInfo = new char[MAX_INFO_SIZE]; //create dynamic msg

sprintf(pInfo,"msg_%d",++count);

PostThreadMessage(nThreadID,MY_MSG,(WPARAM)pInfo,0)//post thread msg

 

/*The explanation information is as follows*/

if(GetMessage(&msg,0,0,0)) //get msg from message queue

{

            switch(msg.message)

            {

            case MY_MSG:

            char * pInfo = (char *)msg.wParam;

            printf("recv %s/n",pInfo);

            delete[] pInfo; //Resources are released here

            break;

            }

}

Do a simple message communication experiment, let the main thread wait for user input, generate different messages, and post these messages to the child threads, and the child threads make different responses according to the generated messages. These child threads can be worker threads or UI threads.

 

 

 

 

 

#include <windows.h>

#include <cstdio>

#include <process.h>

 

#define MY_MSG WM_USER+100

const int MAX_INFO_SIZE = 20;

 

HANDLE hStartEvent; // thread start event

 

// thread function

unsigned __stdcall fun(void *param)

{

    printf("thread fun start/n");

 

    MSG msg;

    PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);

 

    if(!SetEvent(hStartEvent)) //set thread start event

    {

        printf("set start event failed,errno:%d/n",::GetLastError());

        return 1;

    }

   

    while(true)

    {

        if(GetMessage(&msg,0,0,0)) //get msg from message queue

        {

            switch(msg.message)

            {

            case MY_MSG:

                char * pInfo = (char *)msg.wParam;

                printf("recv %s/n",pInfo);

                delete[] pInfo;

                break;

            }

        }

    };

    return 0;

}

 

int main()

{

    HANDLE hThread;

    unsigned nThreadID;

 

    hStartEvent = ::CreateEvent(0,FALSE,FALSE,0); //create thread start event

    if(hStartEvent == 0)

    {

        printf("create start event failed,errno:%d/n",::GetLastError());

        return 1;

    }

 

    //start thread

    hThread = (HANDLE)_beginthreadex( NULL, 0, &fun, NULL, 0, &nThreadID );

    if(hThread == 0)

    {

        printf("start thread failed,errno:%d/n",::GetLastError());

        CloseHandle(hStartEvent);

        return 1;

    }

 

    //wait thread start event to avoid PostThreadMessage return errno:1444

    ::WaitForSingleObject(hStartEvent,INFINITE);

    CloseHandle(hStartEvent);

 

    int count = 0;

    while(true)

    {

        char* pInfo = new char[MAX_INFO_SIZE]; //create dynamic msg

        sprintf(pInfo,"msg_%d",++count);

        if(!PostThreadMessage(nThreadID,MY_MSG,(WPARAM)pInfo,0))//post thread msg

        {

            printf("post message failed,errno:%d/n",::GetLastError());

            delete[] pInfo;

        }

        ::Sleep(1000);

    }

 

    CloseHandle(hThread);

    return 0;

}

 

To change SETTING to multi-threaded

Project->Settings->click C/C tab,

Choose Code Generation in Category, then choose one in Use run-time libray

Multithread configuration

Transfer from: http://blog.csdn.net/liuliu20036/article/details/3879152

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.