实验9 多线程程序设计

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验九多线程程序设计

一、实验目的

1、工作线程的创建;

2、多线程的创建;

3、主程序与线程间数据交换;

4、线程工作状态设置及修改。

二、实验要求

2.1 创建一个窗口,建立子菜单(创建线程(BEGIN_THREAD)、线程关闭(CLOSE)),利用创建线程BEGIN_THREAD,创建许多工作线程,利用线程关闭(CLOSE)所有线程。每个工作线程都对全局变量int gl_i加100,然后在线程中判别全局变量BOOL gl_bclose,当判别为线程结束时,将当前线程获得的gl_i在对话中显示(即中间对话中显示的值)。

注意,由于线程是一个简单的延时后累加的过程,所有随着控制线程是否结束的时间不同,得到的值是不相同的。

控制线程结束,利用线程关闭(CLOSE)实现对gl_bclose的修改。

2.2 同1,要求利用子菜单选择同时启动两个线程,在这两个线程中分别有各自的累加值并在线程中对其进行累加,不过要求两个线程有不同的优先级别,当线程关闭后,显示两线程当前的累计值。

2.3 编写一个线程,功能是将主程序通过利用参数传递方法传递给线程的一个整型数(或一个类)定时累加。建立一个对话窗口,有线程的‘启动’、‘挂起’/‘运行’和‘停止’三个按钮,‘启动按钮’实现启动一个线程,‘挂起’/‘运行’是一个按钮,是根据当前线程的状态设置,显然当线程在‘运行’状况,该按钮应该显示‘挂起’,反之,显示‘运行’,当按该按钮后,使线程处于挂起状态或运行状态,‘停止’按钮显然是停止该线程的运行。另有一个‘MOVE’按钮和一个编辑控件,按‘MOVE’按钮将当前线程中的整型值在编辑控件上显示。

目的:了解线程与主程序间的参数传递。

三、实验过程

3.1首先创建单文档工程,如下图:

3.2 第一部分──线程的创建与结束:

3.2.1添加全局变量:

int gl_i; //计数

BOOL gl_bclose;

//线程控制:true-结束所有线程;false-线程继续执行

3.2.2线程的创建:

线程靠一个CWinThread类的对象来管理,启动一个新线程的方法很简单,用到API函数的AfxBeginThread,定义如下:

CWinThread * AFXAPI AfxBeginThread

(AFX_THREADPROC pfnThreadProc, // 线程函数的地址

LPVOID pParam,//传送到线程函数的参数

int nPriority,// (可选的)线程的优先级,默认的是平常的优先级,

UINT nStackSize,// (可选的)线程的堆栈大小

DWORD dwCreateFlags, // (可选的)如果用户创建的线程在开始的时候在挂起态,而不在运行态,可以设置为

CREATE_SUSPENDED

LPSECURITY_ATTRIBUTES lpSecurityAttrs

// (可选的)线程的安全属性,默认的是和父线程的访问权限一样

);

函数AfxBeginThread 启动新线程并返回一个线程对象指针,然后,新线程和启动新线程的线程同时运行。函数的第一个参数指定线程函数。新线程首先执行这个函数,在这个函数中可以再调用其他函数完成新线程的工作,这个函数执行完毕返回时,新线程结束。线程函数不能是任意定义,必须定义如下:UINT ThreadFunction(LPVOID pParam);

这个函数必须被定义成全局函数,函数的返回类型必须是UINT,必须有一个LPVOID类型的参数,这个参数一般使用AfxBeginThread 函数的第二个参数pParam。函数的返回值在函数中任意定义(但不能返回特殊值

STILL_AVTIVE,它被定义成0X00000l03L,表示线程仍在运行,引起混淆)。

AfxBeginThread函数的具体用法可查阅MSDN。

3.2.3线程函数:

线程函数定义了线程要做什么,在进入这个函数的时候线程开始,退出的时候线程结束。这个函数称为线程函数,定义如下:

UINT ThreadFunction( LPVOID pParam );

这里:ThreadFunction 是线程函数名,就是启动线程函数的第一个参数pfnThreadProc。

参数LPVOID pParam 是启动线程函数的第二个参数,该参数是一个32位数,是在线程对象创建时传送给对象的构造函数。线程函数根据需要进行对参数进行处理,实际上,线程和主程序之间可以利用这个参数实现数据传递。

3.2.4终止线程:

线程终止由两种方法,一种是等待线程函数执行完毕后自动退出,线程退出后创建的线程对象是否自动删除,是由CWinThread 对象的一个成员变量

m_bAutoDelete决定,为TRUE时,线程执行后自动删除创建的CWinThread 对象,否则,在线程结束后,该对象并不删除,需要外部来删除。

可以在线程创建后对m_bAutoDelete 设置。

如:m_pDrawThread -> m_bAutoDelete = FALSE ;

这样,在线程执行结束后并不删除,需要外部去删除:

delete m_pDrawThread;

另一个终止线程的方法是调用MFC函数AfxEndThread:

void AFXAPI AfxEndThread( UINT nExitCode, BOOL bDelete );

延时计数可利用函数:

VOID Sleep(

DWORD dwMilliseconds// 延时长度(单位:毫秒)

);

实验九第一部分最终结果如下图:

第一部分程序如下:

class Ctest9 // 定义一个类

{

public:

Ctest9(){ m_i = 0 ;};

void Set( int i ) { m_i = i ;};

void SetId( int i ) { id = i; };

int Get() { return m_i ;} ;

int GetId() { return id ;} ;

void Inc() { m_i += 1 ;};

private:

int m_i; //累计值

int id; //线程编号} ;

相关文档
最新文档