第10章 多线程编程

上传人:飞*** 文档编号:48606415 上传时间:2018-07-18 格式:PPT 页数:46 大小:485KB
返回 下载 相关 举报
第10章 多线程编程_第1页
第1页 / 共46页
第10章 多线程编程_第2页
第2页 / 共46页
第10章 多线程编程_第3页
第3页 / 共46页
第10章 多线程编程_第4页
第4页 / 共46页
第10章 多线程编程_第5页
第5页 / 共46页
点击查看更多>>
资源描述

《第10章 多线程编程》由会员分享,可在线阅读,更多相关《第10章 多线程编程(46页珍藏版)》请在金锄头文库上搜索。

1、第 10 章 多线程编程Visual C+Visual C+程序设计与应用教程程序设计与应用教程10.1 概述 10.2 线程的创建 10.3 线程的控制 10.4 线程间的通信 10.5 线程间的同步1Visual C+程序设计与应用教程*10.1 概述 第10章 多线程编程 大多数操作系统,可以同时运行几个程序,操作系 统的这种能力称之为多任务处理。Windows操作系统用多进程/线程机制提供对一个应 用程序内多任务的支持,进程与线程之间是密不可分的 ,线程依附于进程,一个进程可包含多个线程。2Visual C+程序设计与应用教程*10.1.1 问题的提出【例10.1】创建一个基于对话框的

2、应用程序Li10_1,其界 面如图下图所示。按下“开始打印”按钮后,模拟启动一个 耗时的打印程序。第10章 多线程编程 3Visual C+程序设计与应用教程*10.1.2 进程和线程进程是应用程序的执行实例,是操作系统分配 资源单位。每个进程是由私有的虚拟地址空间、代码、数 据和其它各种系统资源组成,进程在运行过程中创建 的资源随着进程的终止而被销毁,所使用的系统资源 在进程终止时被释放或关闭。线程是操作系统分配处理器的最基本单元,它 是进程内部的一个独立的执行单元。第10章 多线程编程 4Visual C+程序设计与应用教程*可以用VC+所带的工具Spy+来观察操作系统 管理的进程和线程。

3、打开Word应用程序和Windows附件中的“记事 本”,这样系统内部就产生了两个进程。选择【Tools|Spy+】菜单命令,打开如下图 所示的Spy+应用程序窗口。第10章 多线程编程 5Visual C+程序设计与应用教程*第10章 多线程编程 6Visual C+程序设计与应用教程*第10章 多线程编程 选择【Spy | Processes】菜单命令,在打开的 窗口中可以看到操作系统管理的所有进程的信息,如 下图所示。7Visual C+程序设计与应用教程*10.1.3 MFC对多线程编程的支持多线程的操作由MFC类CWinThread及其派生 类支持,该类的对象代表进程中执行的线程。下

4、图给出了MFC应用程序框架结构类的继承关 系。第10章 多线程编程 8Visual C+程序设计与应用教程*从上图可以看出,MFC应用程序类CWinApp是由 CWinThread类派生而来的,用于启动进程的主线程。另外,MFC还提供了支持多线程同步的同步类,如 CEvent、CCriticalSection、CSemaphore和 CMutex等。也提供了线程同步辅助类CSingleLock和 CMutiLock。第10章 多线程编程 9Visual C+程序设计与应用教程*10.2 线程的创建第10章 多线程编程 MFC中有两类线程,分别称之为工作者线程和用户界 面线程。两者的主要区别在于

5、:工作者线程没有消息循环, 而用户界面线程有自己的消息队列和消息循环。10Visual C+程序设计与应用教程*10.2.1 创建工作者线程创建一个工作者线程,首先需要编写一个希望与应用 程序的其余部分并行运行的自定义函数,该函数称为线程 函数。然后,在程序中合适的地方调用全局函数 AfxBeginThread()创建线程,启动线程函数。第10章 多线程编程 11Visual C+程序设计与应用教程*1.定义线程函数线程函数的固定形式:UINT FunctionName (LPVOID pParam)FunctionName是用户自定义的函数名,LPVOID表示指 向空类型的指针,相当于voi

6、d*,必要时需要把这个指针转 换成所需要的类型。函数的返回值将作为线程的结束码, 线程函数结束后线程就自动终止。函数的返回值如果为0, 表示线程函数正常结束。第10章 多线程编程 12Visual C+程序设计与应用教程*2启动线程函数CWinThread* AfxBeginThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam,int nPriority=THREAD_PRIORITY_NORMAL,UINT nStackSize=0, DWORD dwCreateFlags=0,LPSECURITY_ATTRIBUTES lpSecurityA

7、ttrs= NULL);pfnThreadProc是一个指向线程函数的指针,参数 pParam的类型与线程函数的参数类型完全一致,该参数 为启动线程时传递给线程函数的入口参数。其他几个参数 用于设置线程优先级、线程的堆栈大小、创建时是否立即 运行及线程的安全属性,这4个参数通常使用默认值。第10章 多线程编程 13Visual C+程序设计与应用教程*【例10.2】编写一个创建工作线程的单文档应用程序 Li10_2,当执行【计算素数】菜单命令时启动一个工作线 程,计算11000000之间素数的个数。第10章 多线程编程 14Visual C+程序设计与应用教程*第10章 多线程编程 10.2.

8、2 创建用户界面线程用户界面线程通常用来处理用户输入并响应各种事件 和消息,它是通过自己的消息泵获取从系统接收到的消息 。MFC将为该线程增加一个消息循环,以便能够处理收到 的消息。创建用户界面线程的过程与创建一个工作者线程的过 程完全不同。一个工作者线程用由一个线程函数代表,但 一个用户界面线程的行为由CWinThread类的派生类来控 制。15Visual C+程序设计与应用教程*第10章 多线程编程 创建用户界面线程的AfxBeginThread()函数:CWinThread* AfxBeginThread( CRuntimeClass* pThreadClass,int nPriori

9、ty = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0,DWORD dwCreateFlags=0,LPSECURITY_ATTRIBUTES pSecurityAttrs = NULL );pThreadClass指向一个CRuntimeClass对象,该对 象是用RUNTIME_CLASS宏从CWinThread的派生类创 建的。其他参数的含义与前述的函数AfxBeginThread() 一样。16Visual C+程序设计与应用教程*第10章 多线程编程 在程序中创建一个用户界面线程:AfxBeginThread (RUNTIME_CLASS (

10、class_name); 实参class_name是CWinThread的派生类的名字。17Visual C+程序设计与应用教程*第10章 多线程编程 【例10.3】 在基于对话框的应用程序Li10_3中创建用户界 面线程。每单击一次“用户界面线程”按钮,都会弹出一个 线程对话框,在任何一个线程对话框内按下鼠标左键,都 会弹出一个消息框,效果如下图所示。18Visual C+程序设计与应用教程*10.3 线程的控制第10章 多线程编程 线程控制是指控制线程的状态。从以下几个方面控制线程:创建一个线程、终止一个线程、挂起一个正运行的 线程、激活一个暂停运行的线程、读取和设置线程的优 先级、使当前

11、线程等待一定的时间及放弃一个或多个运 行时间片等。19Visual C+程序设计与应用教程*10.3.1 终止一个线程第10章 多线程编程 当一个工作者线程的线程函数执行一个返回语句 或者调用AfxEndThread( )成员函数时,这个工作者 线程就终止。AfxEndThread()函数原型:void AfxEndThread(UNIT nExitCode);参数nExitCode表示线程的32位退出码。20Visual C+程序设计与应用教程*10.3.2 悬挂和恢复线程第10章 多线程编程 CWinThread类中包含线程悬挂和恢复的成员函数。悬挂就是挂起或暂定线程的运行。悬挂函数:DW

12、ORD CWinThread:SuspendThread();恢复就是激活一个暂停运行的线程,即被悬挂的线程 。恢复函数:DWORD CWinThread:ResumeThread();21Visual C+程序设计与应用教程*10.3.3 线程的优先级第10章 多线程编程 使用CWinThread:SetThreadPriority函数设置线 程的相对优先级:使用CWinThread:GetThreadPriority函数获取线 程的相对优先级:int GetThreadPriority(HANDLE hThread);参数hThread是要设置或获取优先级线程的句柄,参数 nPriorit

13、y就是要设置的优先级。BOOL SetThreadPriority(HANDLE hThread,int nPriority);22Visual C+程序设计与应用教程*第10章 多线程编程 【例10.4】在基于对话框的应用程序Li10_4中,首先创建 两个工作线程,分别控制滑动条及进度条的走动,然后对 线程进行控制,包括挂起、唤醒、停止及优先级的设置。 程序运行界面如下图所示。 23Visual C+程序设计与应用教程*第10章 多线程编程 10.4 线程间的通信一般可以使用全局变量进行通信和自定义消息进行通 信。10.4.1 使用全局变量进行通信对于标准类型的全局变量,建议使用volati

14、le 修饰 符,它告诉编译器无需对该变量作任何的优化,即无需 将它放到一个寄存器中,并且该值可被外部改变。如果 线程间所需传递的信息较复杂,可以定义一个结构,通 过传递指向该结构的指针进行传递信息。接着让线程监 视这个变量,当这个变量符合一定的条件时,表示线程 应该终止。24Visual C+程序设计与应用教程*第10章 多线程编程 10.4.2 使用自定义消息进行通信使用Windows消息来进行通讯,首先需要定义一 个自定义消息,然后,需要时在一个线程中调用全局函 数:PostMessage()向另一个线程发送自定义消息。 PostMessage()函数的原型为:BOOL PostMessa

15、ge(HWND hwnd,UINT Msg,WPARAM wParam,LPARAM lParam);hwnd为发送窗口的句柄,Msg为消息的ID,wParam 和lParam为消息的相关参数。25Visual C+程序设计与应用教程*第10章 多线程编程 【例10.5】完善例10.2中的 Li10_2,Calculateprime() 线程函数执行完后,向主线程发送消息,主线程收到该 消息后再显示计算结果。 26Visual C+程序设计与应用教程*第10章 多线程编程 使隶属于同一进程的各线程协调一致地工作称为 线程的同步。在多线程的环境里,需要对线程进行同步。常用 的同步对象有临界区、互

16、斥、信号量和事件。10.5 线程间的同步27Visual C+程序设计与应用教程*第10章 多线程编程 当多个线程访问临界区时,可以使用临界区对象, 即CCriticalSection类的对象。临界区是一个独占性共享 资源,任一时刻只有一个线程可以拥有临界区。10.5.1 使用CCriticalSection类28Visual C+程序设计与应用教程*第10章 多线程编程 CCriticalSection类的用法有两种:u方法一:单独使用CCriticalSection对象步骤如下:(1) 定义CCriticalSection类的一个全局对象(以使各个线 程均能访问),如:CCriticalSection critical_section; CCriticalSection类的构造函数只有一种形式,即不带任 何参数,如上述代码所示。29Visual C+程序设计与应用教程*第10章

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 商业/管理/HR > 其它文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号