线程间通信
主线程创建子线程必定会为主线程分担一部分工作,这样不可避免的会在这两个线程之间存在消息传递渠道,因此主线程和子线程之间要进行通信。
下面介绍几种通信方式:
- 全局变量:由于同一进程的各个线程之间共享该进程的资源,因此,解决线程间通信最简单的方式是使用全局变量。对于标准类型的全局变量,使用validate修饰符,不让编译器对其优化,因为编译器如果对其优化,可能会导致线程间读取数据的不准确。例如一个变量num:
- int num;
- num = 1;
- num = 2;
- 自定义消息:
可以在一个线程中向另一个线程发送消息来实现线程之间的通信。一个线程向另一个线程发送消息是通过操作系统实现的。当一个线程发送一个消息,操纵系统首先接收到消息,然后把此消息转发到目的线程。
多线程实例6-----自定义消息实现线程间通信
此实例实现简单1到50,1到100,1到150相加,然后把相加结果显示出来。计算结果采用一个子线程实现(CalculateThread类,继承自CWinThread类),然后把计算结果通过消息发送给主线程。
部分代码:
CalculateThread.cpp
- // CalculateThread.cpp : implementation file
- //
- #include "stdafx.h"
- #include "Mthread7.h"
- #include "CalculateThread.h"
- #include "Mthread7Dlg.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /
- // CCalculateThread
- IMPLEMENT_DYNCREATE(CCalculateThread, CWinThread)
- CCalculateThread::CCalculateThread()
- {
- }
- CCalculateThread::~CCalculateThread()
- {
- }
- BOOL CCalculateThread::InitInstance()
- {
- // TODO: perform and per-thread initialization here
- return TRUE;
- }
- int CCalculateThread::ExitInstance()
- {
- // TODO: perform any per-thread cleanup here
- return CWinThread::ExitInstance();
- }
- BEGIN_MESSAGE_MAP(CCalculateThread, CWinThread)
- //{{AFX_MSG_MAP(CCalculateThread)
- // NOTE - the ClassWizard will add and remove mapping macros here.
- ON_THREAD_MESSAGE(WM_CALCULATE,OnCalculate)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /
- // CCalculateThread message handlers
- LRESULT CCalculateThread::OnCalculate(WPARAM wParam, LPARAM lParam)
- {
- int iTemp = 0;
- for (int i=0; i<(int)wParam+1; i++)
- {
- iTemp = i + iTemp;
- }
- Sleep(500);
- //::PostMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_DISPLAY,iTemp,0);
- PostMessage(GetMainWnd()->GetSafeHwnd(),WM_DISPLAY,iTemp,0);
- return 0;
- }
主线程主要是创建子线程,并且发送计算消息给子线程,并且把计算需要的参数通过消息发送给计算线程。
部分代码如下:
- LRESULT CCalculateThread::OnCalculate(WPARAM wParam, LPARAM lParam)
- {
- int iTemp = 0;
- for (int i=0; i<(int)wParam+1; i++)
- {
- iTemp = i + iTemp;
- }
- Sleep(500);
- //::PostMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_DISPLAY,iTemp,0);
- PostMessage(GetMainWnd()->GetSafeHwnd(),WM_DISPLAY,iTemp,0);
- return 0;
- }
执行结果: