C++多线程编程(三)线程间通信

多线程编程之三——线程间通讯

作者:韩耀旭

原文地址:http://www.vckbase.com/document/viewdoc/?id=1707

 

七、线程间通讯

  一般而言,应用程序中的一个次要线程总是为主线程执行特定的任务,这样,主线程和次要线程间必定有一个信息传递的渠道,也就是主线程和次要线程间要进行通信。这种线程间的通信不但是难以避免的,而且在多线程编程中也是复杂和频繁的,下面将进行说明。

  1. 使用全局变量进行通信

    由于属于同一个进程的各个线程共享操作系统分配该进程的资源,故解决线程间通信最简单的一种方法是使用全局变量。对于标准类型的全局变量,我们建议使用volatile 修饰符,它告诉编译器无需对该变量作任何的优化,即无需将它放到一个寄存器中,并且该值可被外部改变。如果线程间所需传递的信息较复杂,我们可以定义一个结构,通过传递指向该结构的指针进行传递信息。
     

  2. 使用自定义消息

    我们可以在一个线程的执行函数中向另一个线程发送自定义的消息来达到通信的目的。一个线程向另外一个线程发送消息是通过操作系统实现的。利用Windows操作系统的消息驱动机制,当一个线程发出一条消息时,操作系统首先接收到该消息,然后把该消息转发给目标线程,接收消息的线程必须已经建立了消息循环。

例程7 MultiThread7

  该例程演示了如何使用自定义消息进行线程间通信。首先,主线程向CCalculateThread线程发送消息WM_CALCULATE,CCalculateThread线程收到消息后进行计算,再向主线程发送WM_DISPLAY消息,主线程收到该消息后显示计算结果。

  1. 建立一个基于对话框的工程MultiThread7,在对话框IDD_MULTITHREAD7_DIALOG中加入三个单选按钮IDC_RADIO1,IDC_RADIO2,IDC_RADIO3,标题分别为1+2+3+4+......+10,1+2+3+4+......+50,1+2+3+4+......+100。加入按钮IDC_SUM,标题为“求和”。加入标签框IDC_STATUS,属性选中“边框”;
  2. 在MultiThread7Dlg.h中定义如下变量:
    protected: 	int nAddend; 

    代表加数的大小。

    分别双击三个单选按钮,添加消息响应函数:

    
    

    [cpp] view plaincopy

    1. void CMultiThread7Dlg::OnRadio1()   
    2. {  
    3.     nAddend=10;  
    4. }  
    5.   
    6. void CMultiThread7Dlg::OnRadio2()   
    7. {  
    8.     nAddend=50;  
    9.       
    10. }  
    11.   
    12. void CMultiThread7Dlg::OnRadio3()   
    13. {  
    14.     nAddend=100;  
    15.       
    16. }  

    并在OnInitDialog函数中完成相应的初始化工作:

    
    

    [c-sharp] view plaincopy

    1. BOOL CMultiThread7Dlg::OnInitDialog()  
    2. {  
    3. ……  
    4.     ((CButton*)GetDlgItem(IDC_RADIO1))->SetCheck(TRUE);  
    5.     nAddend=10;  
    6. ……  

    在MultiThread7Dlg.h中添加:

    
    

    [cpp] view plaincopy

    1. #include "CalculateThread.h"  
    2. #define WM_DISPLAY WM_USER+2  
    3. class CMultiThread7Dlg : public CDialog  
    4. {  
    5. // Construction  
    6. public:  
    7.     CMultiThread7Dlg(CWnd* pParent = NULL); // standard constructor  
    8.     CCalculateThread* m_pCalculateThread;  
    9. ……  
    10. protected:  
    11.     int nAddend;  
    12.     LRESULT OnDisplay(WPARAM wParam,LPARAM lParam);  
    13. ……  
    14.   
    15. 在MultiThread7Dlg.cpp中添加:   
    16. BEGIN_MESSAGE_MAP(CMultiThread7Dlg, CDialog)  
    17. ……  
    18.     ON_MESSAGE(WM_DISPLAY,OnDisplay)  
    19. END_MESSAGE_MAP()  
    20.   
    21. LRESULT CMultiThread7Dlg::OnDisplay(WPARAM wParam,LPARAM lParam)  
    22. {  
    23.     int nTemp=(int)wParam;  
    24.     SetDlgItemInt(IDC_STATUS,nTemp,FALSE);  
    25.   
    26.   return 0;  
    27.   
    28. }  

    以上代码使得主线程类CMultiThread7Dlg可以处理WM_DISPLAY消息,即在IDC_STATUS标签框中显示计算结果。

  3. 双击按钮IDC_SUM,添加消息响应函数:
    
    

    [cpp] view plaincopy

    1. void CMultiThread7Dlg::OnSum()   
    2. {  
    3.     m_pCalculateThread=  
    4.         (CCalculateThread*)AfxBeginThread(RUNTIME_CLASS(CCalculateThread));  
    5.   
    6.     Sleep(500);  
    7.   
    8.     m_pCalculateThread->PostThreadMessage(WM_CALCULATE,nAddend,NULL);  
    9. }  

    OnSum()函数的作用是建立CalculateThread线程,延时给该线程发送WM_CALCULATE消息。

  4. 右击工程并选中“New Class…”为工程添加基类为 CWinThread 派生线程类 CCalculateThread。

    在文件CalculateThread.h 中添加

    
    

    [cpp] view plaincopy

    1. #define WM_CALCULATE WM_USER+1   
    2. class CCalculateThread : public CWinThread  
    3. {  
    4. ……  
    5. protected:  
    6.     afx_msg LONG OnCalculate(UINT wParam,LONG lParam);  
    7. ……  
    8.   
    9. 在文件CalculateThread.cpp中添加   
    10. LONG CCalculateThread::OnCalculate(UINT wParam,LONG lParam)  
    11. {  
    12.     int nTmpt=0;  
    13.     for(int i=0;i<=(int)wParam;i++)  
    14.     {  
    15.         nTmpt=nTmpt+i;  
    16.     }  
    17.   
    18.     Sleep(500);  
    19.     ::PostMessage((HWND)(GetMainWnd()->GetSafeHwnd()),WM_DISPLAY,nTmpt,NULL);  
    20.   
    21.     return 0;  
    22. }  
    23. BEGIN_MESSAGE_MAP(CCalculateThread, CWinThread)  
    24.     //{{AFX_MSG_MAP(CCalculateThread)  
    25.         // NOTE - the ClassWizard will add and remove mapping macros here.  
    26.     //}}AFX_MSG_MAP  
    27.     ON_THREAD_MESSAGE(WM_CALCULATE,OnCalculate)  
    28. //和主线程对比,注意它们的区别  
    29. END_MESSAGE_MAP()  

    在CalculateThread.cpp文件的开头添加一条:

    #include "MultiThread7Dlg.h" 

      以上代码为 CCalculateThread 类添加了 WM_CALCULATE 消息,消息的响应函数是 OnCalculate,其功能是根据参数 wParam 的值,进行累加,累加结果在临时变量nTmpt中,延时0.5秒,向主线程发送WM_DISPLAY消息进行显示,nTmpt作为参数传递。

编译并运行该例程,体会如何在线程间传递消息。

(未完待续)

 

from:http://blog.csdn.net/yanpingsz/article/details/5891693 

时间: 2024-10-26 05:26:16

C++多线程编程(三)线程间通信的相关文章

多线程编程之三——线程间通讯

七.线程间通讯 一般而言,应用程序中的一个次要线程总是为主线程执行特定的任务,这样,主线程和次要线程间必定有一个信息传递的渠道,也就是主线程和次要线程间要进行通信.这种线程间的通信不但是难以避免的,而且在多线程编程中也是复杂和频繁的,下面将进行说明. 使用全局变量进行通信 由于属于同一个进程的各个线程共享操作系统分配该进程的资源,故解决线程间通信最简单的一种方法是使用全局变量.对于标准类型的全局变量,我们建议使用volatile 修饰符,它告诉编译器无需对该变量作任何的优化,即无需将它放到一个寄

多线程编程之 ---线程间通讯

下载源代码 七.线程间通讯 一般而言,应用程序中的一个次要线程总是为主线程执行特定的任务,这样,主线程和次要线程间必定有一个信息传递的渠道,也就是主线程和次要线程间要进行通信.这种线程间的通信不但是难以避免的,而且在多线程编程中也是复杂和频繁的,下面将进行说明. 使用全局变量进行通信 由于属于同一个进程的各个线程共享操作系统分配该进程的资源,故解决线程间通信最简单的一种方法是使用全局变量.对于标准类型的全局变量,我们建议使用volatile 修饰符,它告诉编译器无需对该变量作任何的优化,即无需将

Python多线程编程(八):使用Event实现线程间通信_python

使用threading.Event可以实现线程间相互通信,之前的Python:使用threading模块实现多线程编程七[使用Condition实现复杂同步]我们已经初步实现了线程间通信的基本功能,但是更为通用的一种做法是使用threading.Event对象.使用threading.Event可以使一个线程等待其他线程的通知,我们把这个Event传递到线程对象中,Event默认内置了一个标志,初始值为False.一旦该线程通过wait()方法进入等待状态,直到另一个线程调用该Event的set

vc 基于对话框多线程编程实例——线程之间的通信

 vc基于对话框多线程编程实例--线程之间的通信 实例:  

volatile关键字与线程间通信

Java内存模型 现在计算机普遍使用多处理器进行运算,并且为了解决计算机存储设备和处理器的运算速度之间巨大的差距,引入了高速缓存作为缓冲, 缓存虽然能极大的提高性能,但是随之带来的缓存一致性的问题, 例如,当多个处理器同时操作同一个内存地址,可能会导致各自的缓存数据不一致,由此产生冲突问题, 内存模型就是定义一套充分必要的规范,这些规范使得其他处理器对内存的写操作对当前处理器可见,或者当前处理器的写操作对其他处理器可见. 类似物理上的计算机系统,Java虚拟机规范中也定义了一种Java内存模型,

深入解析Java的线程同步以及线程间通信_java

Java线程同步 当两个或两个以上的线程需要共享资源,它们需要某种方法来确定资源在某一刻仅被一个线程占用.达到此目的的过程叫做同步(synchronization).像你所看到的,Java为此提供了独特的,语言水平上的支持. 同步的关键是管程(也叫信号量semaphore)的概念.管程是一个互斥独占锁定的对象,或称互斥体(mutex).在给定的时间,仅有一个线程可以获得管程.当一个线程需要锁定,它必须进入管程.所有其他的试图进入已经锁定的管程的线程必须挂起直到第一个线程退出管程.这些其他的线程被

java线程间通信

线程通信的目标是使线程间能够互相发送信号.另一方面,线程通信使线程能够等待其他线程的信号. 例如,线程B可以等待线程A的一个信号,这个信号会通知线程B数据已经准备好了.本文将讲解以下几个JAVA线程间通信的主题: 1.通过共享对象通信 2.忙等待 3.wait(),notify()和notifyAll() 4.丢失的信号 5.假唤醒 6.多线程等待相同信号 7.不要对常量字符串或全局对象调用wait() 1.通过共享对象通信 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值.线程A在一

什么是.Net的异步机制(线程间通信)

前几篇文章我已经对异步的操作进行的详细的解释.异步操作也是线程的一种,当我们开始一个异步操作(新线程),完成调用后需要和其他线程通信(可能需要告知状态信息),这时候我们就需要线程间的通信编程. 线程间通信 我们看下面的图 图1 我们来看线程间通信的原理:线程(Thread B)和线程(Thread A)通信, 首先线程A 必须实现同步上下文对象(Synchronization Context), 线程B通过调用线程A的同步上下文对象来访问线程A,所有实现都是在同步上下文中完成的.线程B有两种方式

java线程间通信[实现不同线程之间的消息传递(通信),生产者和消费者模型]

线程通信,线程之间的消息传递: 多个线程在操作同一个资源,但对共享资源的操作动作不同:它们共享同一个资源,互为条件,相互依赖,相互通信让任务向前推进. 线程的同步,可以解决并发更新同一个资源,实现线程同步;但不能用来实现线程间的消息传递. 线程通信生产者和消费者和仓库是个典型模型: 生产者:没有生产之前通知消费者等待,生产产品结束之后,马上通知消费者消费 消费者:没有消费之前通知生产者等待,消费产品结束之后,通知生产者继续生产产品以供消费 线程通信:使用java中Object中提供的: publ