分享
 
 
 

线程通信初探

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

进程是运行中的程序,有独立的内存,文件句柄和其它的系统资源,一个独立的进程可以包含多条执行路径,即线程。一个函数可以被多个线程访问,多个线程可以访问同一个全局变量。

Windows提供两种线程,用户界面线程和辅助线程。用户界面线程有窗口,因此有自己的消息循环,辅助线程没有窗口,不需要处理消息。但是辅助线程非常有用而且很容易编程,比如程序在某个运行时间要完成多个(很笨重的)任务时,显然,辅助线程的使用会使程序的运行效率大大的提高。但是,线程间的通信是一个必须解决的问题。

下面我们就来讨论一下线程间的通信的问题:

一.线程的管理

1.线程的启动:

在使用辅助线程时,我们必须为线程写一个全局函数,它的返回值必须为 UINT类型,而且必须有LPVOID类型的参数,启动线程调用下面的函数:

CWinThread* pThread=AfxBeginThread(

AFX_THREADPPOC ThreadProc,

LPVOID pParam,

int nPriority,

UINT nStackSize,

DWORD dwCreateFlags,

LPSECURITY_ATTRIBUTES lpSecurityAttrs);

全局函数必须定义为 UINT ThreadProc(LPVOID pParam);

AfxBeginThread会立即返回一个指向新创建的线程对象的指针,用来管理线 程,包括挂起和恢复线程的运行,但是线程对象没有成员函数来中止线程的运 行。AfxBeginThread的第二个参数是一个32位的值,用来传给全局函数;第三 个参数用来设定线程的优先级;而第四和第六个参数用来指定线程堆栈大小和 安全性,一般采用默认值0;第五个参数用来设定创建线程对象的方式,0为立 即执行,CREATE_SUSPEND为线程通过ResumeThread后才执行。

而线程优先级的设置和获得可以通过下面的两个函数来实现:

pThread->SetThreadPriority(THREAD_PRIORITY_ABOVE_NOMAL);和

int nPriority=pThread->GetThreadPriority();

2.线程的中止:

可以调用MFC的AfxEndThread函数;

3.检查线程是否结束:

调用API函数GetExitCodeThread,

DWORD ExitCode ;

::GetExitCodeThread(pThread->m_hThread,&ExitCode );

if(ExitCode==STILL_ACTIVE)

//运行中

else //线程已经中止

二.主线程和辅助线程的通信

主线程和辅助线程间的通信方式有很多种,最简单的就是利用全局变量。 这里利用消息通信是行不通的,因为辅助线程没有消息循环,不能够利用 Windows消息。

下面我们用一个例子来说明。在例子中,我们写一个非常笨的函数,如实 现500*3000*3000的加法数据处理函数Add(int nCount);

我们在对话框上放置Start、Cancel按钮和一个用来表示数据处理进度的进度条 。

1.利用全局变量来实现主线程和辅助线程的通信:

我们编写全局函数如下:

UINT ThreadProc(LPVOID pParam)

{

nCount=0;//全局变量

while(nCount<500)

{

Add(nCount);

::InterlockedIncrement((long*)&ncount);

}

return 0;

}

函数InterlockIncrement阻塞其它的线程,当计数器递增时防止其它的线程访问nCount。

2.利用消息实现辅助线程和主线程的通信:

主线程有一个窗口,有消息循环,我们可以在调用AfxBeginThread时把窗口句柄传递给辅助线程,我们通过post方式传递消息,在函数退出时,给窗口发送一个消息。

重新编写线程函数如下:

int nCount=0;

UINT ThreadProc(LPVOID pParam)

{

while(nCount<500)

{

::InterlockedIncrement((long*)&ncount);

Add(nCount);

}

::PostMessage(

(HWND)pParam,

WM_THREADFINISHED,//用户自定义消息

0,0);

return 0;

}

编写OnStart函数:

void CThreadDlg::OnStart()

{

m_nTimer=SetTimer(1,100,NULL);//0.1秒

ASSERT(m_nTimer!=0);

GetDlgItem(IDC_START)->EnableWindow(FALSE);

AfxBeginThread(ThreadProc,GetSafeHwnd(),THREAD_PROIRITY_NOMAL);

}

编辑OnCancel函数如下:

void CThreadDlg::OnCancel()

{

if(nCount==0)

CDialog::OnCancel();

else nCount=500;

}

处理OnThreadFinished函数

HRESULT CThreadDlg::OnThreadFinished(WPARAM wParam,LPARAM lParam)

{

CDialog::OnOk();

return 0;

}

3.用事件使线程同步:

利用WaitForSingleObject函数

在stdafx.h中写入下面一行

#include <afxmt.h>//由于使用了事件

声明两个全局变量

CEvent m_start,m_kill;

在初始化函数中启动线程;

重新编写OnStart函数:

void CThreadDlg::OnStart()

{

m_nTimer=SetTimer(1,100,NULL);//0.1秒

ASSERT(m_nTimer!=0);

GetDlgItem(IDC_START)->EnableWindow(FALSE);

m_start.SetEvent();

}

重新编辑OnCancel函数如下:

void CThreadDlg::OnCancel()

{

if(nCount==0)

m_start.SetEvent();

else m_kill.SetEvent();

}

编写全局函数如下:

UINT ThreadProc(LPVOID pParam)

{

::WaitForSingleObject(m_start,INFINITE);

while(nCount<500)

{

Add(nCount);

if(::WaitForSingleObject(m_start,0)=WAIT_OBJECT_0)

break;

}

::PostMessage(

(HWND)pParam,

WM_THREADFINISHED,//用户自定义消息

0,0);

return 0;

}

其中第一个WaitForSingleObject的调用等待启动事件,INFINITE使其等待直到启动事件有信号。第二个调用若有信号,立即返回,中止线程。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有