线程间的通信

线程间的通信是多线程编程中的关键,包括全局变量、参数传递、消息传递和线程同步法。全局变量是最简单的方法,但要注意并发修改可能导致的问题。参数传递是官方标准,适用于主线程向子线程传递信息。消息传递,如PostThreadMessage,能实现任意线程间的通信。线程同步用于协调线程活动,确保数据正确和避免死锁。
摘要由CSDN通过智能技术生成

线程间的通信

1.线程之间的通信简介

一般而言,在一个应用程序中(即进程),一个线程往往不是孤立存在的,常常需要和其它线程通信,以执行特定的任务。如主线程和次线程,次线程与次线程,工作线程和用户界面线程等。这样,线程与线程间必定有一个信息传递的渠道。这种线程间的通信不但是难以避免的,而且在多线程编程中也是复杂和频繁的。线程间的通信涉及到4个问题:

(1) 线程间如何传递信息

(2)  线程之间如何同步,以使一个线程的活动不会破坏另一个线程的活动,以保证计算结果的正确合理

(3)  当线程间具有依赖关系时,如何调度多个线程的处理顺序

(4)  如何避免死锁问题

在windows系统中线程间的通信一般采用四种方式:全局变量方式、消息传递方式、参数传递方式和线程同步法。下面分别作介绍。

2.全局变量方式

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

实例演示

该实例采用全局变量来控制时间显示线程的显示格式,比较简单。

主要的代码如下:

.h头文件

//线程函数声明

DWORD WINAPIThreadProc(LPVOIDlpParam);

protected:

HANDLE m_hThread;//线程句柄

      DWORD  m_nThread;//线程ID

.cpp实现文件

volatileBYTE m_nShowFlag = 31;//定义全局变量,用于控制显示时间的格式。volatile 修饰符的作用是告诉编译器无需对该变量作任何的优化,即无需将它放到一个寄存器中。

//创建显示时间的线程,参数无

 m_hThread =CreateThread(NULL,0,ThreadProc,NULL,0,&m_nThread);

//线程执行函数,用于实时显示时间,并按规定格式显示

DWORD WINAPIThreadProc(LPVOID lpParam)

{

      while(m_nShowFlag

      {

           CTime time

           CString strTime,strFormat

           time=CTime::GetCurrentTime();

           strFormat = "%H:%M";

           if (m_nShowFlag&2)

           { //日期

                 strFormat = "%Y-%m-%d" + strFormat;

           }

           if (m_nShowFlag&4)

           { //秒钟

                 strFormat += ":%S";

           }

           if (m_nShowFlag&8)

           { //周数

                 strFormat += "%W";

           }

           if (m_nShowFlag&16)

           { //星期

                 strFormat += "%a";

           }

      strTime=time.Format(strFormat); 

      ::SetDlgItemText(AfxGetApp()->m_pMainWnd->m_hWnd,IDC_STATIC_TIME,strTime); 

      Sleep(100); 

      } 

      return 0;

}

运行效果:

工程源码下载地址:

http://download.csdn.net/detail/cbnotes/4962315

欢迎大家修改和指正。

注意事项:

(1)  全局变量最好放在.CPP文件的起始处,而不要放在.h头文件中,否则将出现重复链接的编译错误。定义全局变量时最好显式初始化,默认初始值为零

(2)  注意语句

::SetDlgItemText(AfxGetMainWnd()->m_hWndIDC_STATIC_TIME,strTime);在VC6.0中可以通过,但在VC2008却出错,这是因为在VC2008中不支持AfxGetMainWnd()->m_hWnd来获取HWND,但可以采AfxGetApp()->m_pMainWnd->m_hWnd来获取。所以上面的语句更改为:

::SetDlgItemText(AfxGetApp()->m_pMainWnd->m_hWnd,IDC_STATIC_TIME,strTime); 

(3)  用全局变量方式来实现多线程的通信比较简单实用,单注意最好不要多个线程对它进行修改,否则将可能出错,这将在后面会具体讲解。

3.参数传递方式

该方式是线程通信的官方标准方法,多数情况下,主线程创建子线程并让其子线程为其完成特定的任务,主线程在创建子线程时,可以通过传给线程函数的参数和其通信,三类创建线程的函数都支持参数的传递(哪三类?看前面的介绍吧!)。所传递的参数是一个32位的指针,该指针不但可以指向简单的数据,而且可以指向结构体或类等复杂的抽象数据类型。

实例演示

下面将分别简单演示三类创建线程时提供参数传递的方法。

主要的代码如下:

.h头文件

//线程函数声明

DWORD WINAPI ThreadFunc1(LPVOID lpParam);//线程函数

void  ThreadFunc2(void *pArg);           //线程函数

UINT  ThreadFunc3(LPVOID lpParam);//线程函数

//全局函数

POINT GetRandPoint();//得到随机点的坐标

//结构体定义,用于向线程传递多个参数

struct threadInfo

{

      HWND        hWnd;//主窗口句柄

      COLORREF    clrPen;//画笔颜色

};

.cpp实现文件

//开始创建线程:创建个线程

void CMultThreadComm2Dlg::OnStart(void)

{

      //线程:使用win32 API 创建:实时显示时间

      m_hThread1 = CreateThread(NULL,0,ThreadFunc1,&m_stTime.m_hWnd,0,NULL);//

      //线程:使用CRT 创建:随机画线

     

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值