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

    http://www.cppblog.com/sandy/archive/2009/02/14/2320.html


    PostThreadMessage的原型是这样的

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

    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;
    }
     

  • 相关阅读:
    简单工作流实现思路总结
    (转)基于SAML的单点登录介绍
    Kerberos简介
    (转)Java NIO框架Mina、Netty、Grizzly介绍与对比
    职场老好人为何没发展
    如何改变、摆脱职场老好人
    线程的状态转换图
    设计模式分类
    (转)简单的RPC java实现 .
    MYSQL导入CSV格式文件数据执行提示错误(ERROR 1290): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement.
  • 原文地址:https://www.cnblogs.com/LeoWong/p/1944988.html
Copyright © 2011-2022 走看看