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

作者:韩耀旭

原文地址: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; 

    代表加数的大小。

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

    1. void CMultiThread7Dlg::OnRadio1()
    2. {
    3. nAddend=10;
    4. }
    5. void CMultiThread7Dlg::OnRadio2()
    6. {
    7. nAddend=50;
    8. }
    9. void CMultiThread7Dlg::OnRadio3()
    10. {
    11. nAddend=100;
    12. }
    并在OnInitDialog函数中完成相应的初始化工作:
    [c-sharp] view plaincopy
    1. BOOL CMultiThread7Dlg::OnInitDialog()
    2. {
    3. ……
    4. ((CButton*)GetDlgItem(IDC_RADIO1))->SetCheck(TRUE);
    5. nAddend=10;
    6. ……

    在MultiThread7Dlg.h中添加:

    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. 在MultiThread7Dlg.cpp中添加:
    15. BEGIN_MESSAGE_MAP(CMultiThread7Dlg, CDialog)
    16. ……
    17. ON_MESSAGE(WM_DISPLAY,OnDisplay)
    18. END_MESSAGE_MAP()
    19. LRESULT CMultiThread7Dlg::OnDisplay(WPARAM wParam,LPARAM lParam)
    20. {
    21. int nTemp=(int)wParam;
    22. SetDlgItemInt(IDC_STATUS,nTemp,FALSE);
    23. return 0;
    24. }

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

  3. 双击按钮IDC_SUM,添加消息响应函数:
    1. void CMultiThread7Dlg::OnSum()
    2. {
    3. m_pCalculateThread=
    4. (CCalculateThread*)AfxBeginThread(RUNTIME_CLASS(CCalculateThread));
    5. Sleep(500);
    6. m_pCalculateThread->PostThreadMessage(WM_CALCULATE,nAddend,NULL);
    7. }
    OnSum()函数的作用是建立CalculateThread线程,延时给该线程发送WM_CALCULATE消息。
  4. 右击工程并选中“New Class…”为工程添加基类为 CWinThread 派生线程类 CCalculateThread。

    在文件CalculateThread.h 中添加

    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. 在文件CalculateThread.cpp中添加
    9. LONG CCalculateThread::OnCalculate(UINT wParam,LONG lParam)
    10. {
    11. int nTmpt=0;
    12. for(int i=0;i<=(int)wParam;i++)
    13. {
    14. nTmpt=nTmpt+i;
    15. }
    16. Sleep(500);
    17. ::PostMessage((HWND)(GetMainWnd()->GetSafeHwnd()),WM_DISPLAY,nTmpt,NULL);
    18. return 0;
    19. }
    20. BEGIN_MESSAGE_MAP(CCalculateThread, CWinThread)
    21. //{{AFX_MSG_MAP(CCalculateThread)
    22. // NOTE - the ClassWizard will add and remove mapping macros here.
    23. //}}AFX_MSG_MAP
    24. ON_THREAD_MESSAGE(WM_CALCULATE,OnCalculate)
    25. //和主线程对比,注意它们的区别
    26. 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

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

  1. Java多线程编程(6)--线程间通信(下)

      因为本文的内容大部分是以生产者/消费者模式来进行讲解和举例的,所以在开始学习本文介绍的几种线程间的通信方式之前,我们先来熟悉一下生产者/消费者模式.   在实际的软件开发过程中,经常会碰到如下场景 ...

  2. Java多线程编程核心技术---线程间通信(二)

    通过管道进行线程间通信:字节流 Java提供了各种各样的输入/输出流Stream可以很方便地对数据进行操作,其中管道流(pipeStream)是一种特殊的流,用于在不同线程间直接传送数据,一个线程发送 ...

  3. Java多线程编程核心技术---线程间通信(一)

    线程是操作系统中独立的个体,但这些个体如果不经过特殊处理就不能成为一个整体.线程间的通信就是成为整体的必用方案之一.线程间通信可以使系统之间的交互性更强大,在大大提高CPU利用率的同时还会使程序员对各 ...

  4. Java多线程编程(5)--线程间通信

    一.等待与通知   某些情况下,程序要执行的操作需要满足一定的条件(下文统一将其称之为保护条件)才能执行.在单线程编程中,我们可以使用轮询的方式来实现,即频繁地判断是否满足保护条件,若不满足则继续判断 ...

  5. iOS多线程编程之线程间的通信(转载)

    一.简单说明 线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任务后,转到另1个线程继续执行任务 ...

  6. java多线程同步以及线程间通信详解&消费者生产者模式&死锁&Thread.join()(多线程编程之二)

    本篇我们将讨论以下知识点: 1.线程同步问题的产生 什么是线程同步问题,我们先来看一段卖票系统的代码,然后再分析这个问题: package com.zejian.test; /** * @author ...

  7. [javaSE] 并发编程(线程间通信)

    新建一个资源类Resource 定义成员变量String name 定义成员变量int age 新建一个输入类Input,实现Runnable接口 定义一个构造方法Input(),传入参数:Resou ...

  8. 《JAVA多线程编程核心技术》 笔记:第三章:线程间通信

    一. 等待/通知机制:wait()和notify()1.1.使用的原因:1.2 具体实现:wait()和notify()1.2.1 方法wait():1.2.2 方法notify():1.2.3 wa ...

  9. Java多线程编程(三)线程间通信

    线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体.线程间的通信就是成为整体的必用方案之一,可以说,使线程间进行通信后,系统之间的交互性会更强大,在大大提高CPU利用率的同时 ...

随机推荐

  1. Handle 消息机制

    android中Handle类的主要作用: 1.在新启动的线程中发送给消息 2.在主线程获取.处理消息 为什么要用Handle这样的一个机制: 因为在Android系统中UI操作并不是线程安全的,如果 ...

  2. 自学HTML5第三节(拖放效果)

    今天来看看网页上的拖放效果,首先来看看什么是拖放———— 拖放 拖放是一种常见的特性,即抓取对象以后拖到另一个位置. 在 HTML5 中,拖放是标准的一部分,任何元素都能够拖放. 浏览器支持 Inte ...

  3. python--执行文件的绝对路径

    1.__file__属性对应文件名. 2.os.path.realpath(__file__)这样就可以得到文件的绝对路径.

  4. Qt部件--烧肉

    1,QSplitter

  5. 一张图告诉你如何优化web 性能

  6. Linux学习十七、正规表达式练习题

    情境模拟题一:透过 grep 搜寻特殊字串,并配合数据流重导向来处理大量的文件搜寻问题. 目标:正确的使用正规表示法: 前提:需要了解数据流重导向,以及透过子命令 $(command) 来处理档名的搜 ...

  7. (转) iOS深入学习(Block全面分析)

    本文翻译自苹果的文档,有删减,也有添加自己的理解部分. 如果有Block语法不懂的,可以参考fuckingblocksyntax,里面对于Block 为了方便对比,下面的代码我假设是写在ViewCon ...

  8. JavaScript-1.最简单的程序之网页弹出对话框,显示为Warning---ShinePans

    代码: <html> <head> <meta http-equiv="content-type" content="text/html;c ...

  9. javaScript滚动新闻之上下左右平滑滚动

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  10. HDU 4729 An Easy Problem for Elfness (主席树,树上第K大)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题意:给出一个带边权的图.对于每一个询问(S , ...