zoukankan      html  css  js  c++  java
  • 线程间通信的三种方法 (转)

    http://www.cnblogs.com/puxidun/archive/2009/12/06/1618142.html

    线程间通信的三种方法

    多线程通信的方法主要有以下三种: 

    1.全局变量

    进程中的线程间内存共享,这是比较常用的通信方式和交互方式。

    注:定义全局变量时最好使用volatile来定义,以防编译器对此变量进行优化。

     

    2.Message消息机制

    常用的Message通信的接口主要有两个:PostMessage和PostThreadMessage,

    PostMessage为线程向主窗口发送消息。而PostThreadMessage是任意两个线程之间的通信接口。

    2.1.PostMessage() 
    函数原型:

        B00L PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);

    参数:
        hWnd:其窗口程序接收消息的窗口的句柄。可取有特定含义的两个值:
        HWND.BROADCAST:消息被寄送到系统的所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口
    和弹出式窗口。消息不被寄送到子窗口。
        NULL:此函数的操作和调用参数dwThread设置为当前线程的标识符PostThreadMessage函数一样。
        Msg:指定被寄送的消息。
        wParam:指定附加的消息特定的信息。
        IParam:指定附加的消息特定的信息。
        返回值:如果函数调用成功,返回非零值:如果函数调用失败,返回值是零。

    MS还提供了SendMessage方法进行消息间通讯,SendMessage(),他和PostMessage的区别是:

    SendMessage是同步的,而PostMessage是异步的。SendMessage必须等发送的消息执行之后,才返回。

    2.2.PostThreadMessage()

    PostThreadMessage方法可以将消息发送到指定线程。

    函数原型:BOOL PostThreadMessage(DWORD idThread,UINT Msg,WPARAM wParam, LPARAM lParam);

    参数除了ThreadId之外,基本和PostMessage相同。

    目标线程通过GetMessage()方法来接受消息。

    注:使用这个方法时,目标线程必须已经有自己的消息队列。否则会返回ERROR_INVALID_THREAD_ID错误。可以用
    PeekMessage()给线程创建消息队列。

    3.CEvent对象

    CEvent为MFC中的一个对象,可以通过对CEvent的触发状态进行改变,从而实现线程间的通信和同步。
     
     

    线程间通信可以通过下列三种方法:

    1)使用全局变量实现线程间通信

    2)使用消息实现线程间通信

    3)使用CEvent类实现线程间通信 

    使用全局变量实现线程间通信:

        定义一个全局变量,不同的线程间可以通过修改全局变量的值来进行通信。例如:定义一个控制线程的全局变量

        volatile int  threadController;

    当 threadController值为1时,线程running;当threadController为0时,线程stop, 所以可以通过修改threadController的值来控制线程的运行。

    使用消息实现线程间通信:

      步骤:

        1)在View.h中定义消息:

          例如:  

          const WM_THREAD_SENDMESS=WM_USER+20;

         2)在view.h中添加消息函数声明:    

             例如:
             afx_msg int  OnThreadSendmess();
          3)在view.cpp中添加消息映射:
              ON_MESSAGE(WM_THREAD_SENDMESS,OnThreadSendmess)
          4)在view.cpp中添加OnThreadSendmess()的实现函数;
          5)在线程函数中添加PostMessage消息Post函数;

         UINT TreadProc(LPVOID param)

            {
                 CThreadTestApp *pApp=(CThreadTestApp *) AfxGetApp();
                     CMainFrame *pMainFrame = (CMainFrame *)pApp->GetMainWnd();
                      CThreadTestView *pView = (CThreadTestView *) pMainFrame->GetActiveView();
                      pView->m_strMessage = “启动了一个线程” ;
                      while(threadController)
                      {
                           ::Sleep(1000);
                           ::PostMessage((HWND)param, WM_THREAD_SENDMESS, 0, 0);
                           }
                          pView->m_iTime =0;
                          pView->m_strMessage = “线程结束”;
                          return 0;
    }
          当执行到PostMessage函数时,就会产生在线程中产生一个消息,在主程序中触发相应的消息处理函数, 即完成了不同线程间的通信。
    使用CEvent类实现线程间通信
          (1) Event对象:有两种状态:通信状态和非通信状态;
          (2)创建一个CEvent类的对象:CEvent  threadStart;它默认处在未通信状态;
          (3)threadStart.SetEvent();使其处于通信状态;
          (4)调用WaitForSingleObject()来监视CEvent对象;
             ::WaitForSingleObject(threadStart.m_hObject, INFINITE
  • 相关阅读:
    大学总结(一)
    关于数组名与指针的相互转换
    错误:无法执行操作,因为未将指定的 Storyboard 应用到此交互控件的对象
    延迟初始化 (Lazy Initialization)
    Sql Server 中 GAM、SGAM、PAM、IAM、DCM 和 BCM 的详解与区别
    Xml格式的字符串(string)到DataSet(DataTable)的转换
    Sql Server 内存用不上的解决办法
    Sql Server 管理区分配(GAM,SGAM)和可用空间(PAM)的原理
    Sql Server LightWeight Pooling(纤程) 选项
    在线 Sql Server 服务无法启动的解决办法
  • 原文地址:https://www.cnblogs.com/wb118115/p/2824069.html
Copyright © 2011-2022 走看看