zoukankan      html  css  js  c++  java
  • 转载使用PostThreadMessage在Win32线程间传递消息

    PostThreadMessage

    This function places a message in the message queue of the specified thread and then returns without waiting for the thread to process the message.

    BOOL PostThreadMessage(
    DWORD idThread,
    UINT Msg,
    WPARAM wParam,
    LPARAM lParam
    );

    Parameters

    idThread
    [in] Identifier of the thread to which the message will be posted.
    Msg
    [in] Specifies the type of message to be posted.
    wParam
    [in] Specifies additional message-specific information.
    lParam
    [in] Specifies additional message-specific information.

    Return Values

    Nonzero indicates success. Zero indicates failure. To get extended error
    information, call GetLastError. GetLastError
    returns ERROR_INVALID_THREAD_ID if idThread is not a valid thread
    identifier.


    Remarks

    The thread to which the message is posted retrieves the message by calling
    the GetMessage or PeekMessage function. The hwnd member
    of the returned MSG structure is NULL.

    PostThreadMessage可以用于线程之间的异步通讯,因为它不用等待调用者返回,
    这也许是线程通讯中最简单的一种方法了。

    但是要注意以下问题
    1 .PostThreadMessage有时会失败,报1444错误(Invalid thread identifier. )
    其实这不一定是线程不存在的原因,也有可能是线程不存在消息队列(message queue)造成的。
    事实上,并不是每个thread都有message queue,那如何让thread具有呢?
    答案是,至少调用message相关的function一次,比如GetMessage,PeekMessage。

    2.如果是post动态分配的memory给另外一个thread,要注意内存的正确释放。

    3.PostThreadMessage不能够post WM_COPYDATE之类的同步消息,否则会报错

    4.最好不要使用PostThreadMessage post message给一个窗口,使用PostMessage替代。

    下面是我写的一个比较严整的例子,仅供参考。

    #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;
    }
  • 相关阅读:
    Java 跨系统开发隐患(一)
    SpringBoot邮件推送功能
    基于图灵api的Python机器人
    JSP编码问题解决方法
    记一次数据结构课设
    基于百度语音识别API的Python语音识别小程序
    帝国cms过滤采集内容
    如何批量取消文章审核
    评论时判断会员是否登录
    帝国cms把文章加入到收藏夹代码
  • 原文地址:https://www.cnblogs.com/kex1n/p/2023504.html
Copyright © 2011-2022 走看看