C++程序设计与应用 教学课件 ppt 作者 周仲宁 2 courseware16

上传人:E**** 文档编号:89190939 上传时间:2019-05-21 格式:PPT 页数:86 大小:540.50KB
返回 下载 相关 举报
C++程序设计与应用 教学课件 ppt 作者 周仲宁 2 courseware16_第1页
第1页 / 共86页
C++程序设计与应用 教学课件 ppt 作者 周仲宁 2 courseware16_第2页
第2页 / 共86页
C++程序设计与应用 教学课件 ppt 作者 周仲宁 2 courseware16_第3页
第3页 / 共86页
C++程序设计与应用 教学课件 ppt 作者 周仲宁 2 courseware16_第4页
第4页 / 共86页
C++程序设计与应用 教学课件 ppt 作者 周仲宁 2 courseware16_第5页
第5页 / 共86页
点击查看更多>>
资源描述

《C++程序设计与应用 教学课件 ppt 作者 周仲宁 2 courseware16》由会员分享,可在线阅读,更多相关《C++程序设计与应用 教学课件 ppt 作者 周仲宁 2 courseware16(86页珍藏版)》请在金锄头文库上搜索。

1、第16章 多任务与多线程编程,C+高级编程,本章主要教学内容,进程与线程 线程的种类与MFC同步类 线程的使用 线程的同步及常用的同步对象,第16章 多任务与多线程编程,16.1 程序、进程和线程概述 16.2 线程的种类 16.3 线程的创建、启动和终止 16.4 线程的操作和管理 16.5 在VC+环境中使用同步对象 16.6 本章小结 16.7 思考与练习,16.1 程序、进程和线程概述,16.1.1 多任务、进程和线程,1Windows3.x的协同多任务,如何解决后台工作和对用户的随时响应之间的协同?详见教材P27。,Windows3.x对应用程序的CPU控制权的调度方式: 协同式多任

2、务。其特点详见教材P27。,补充知识:什么是模态对话框和非模态对话框? 见附带文件1。,16.Windows95/NT的抢先式多任务,Windows95/NT对应用程序的CPU控制权的 调度方式:抢先式多任务。其特点详见教材P28。,16.1.1 多任务、进程和线程,3进程与线程,16.1.1 多任务、进程和线程,进程由私有虚拟地址空间、代码、数据和其它操作系统资源(如进程创建的文件、同步对象等)组成。,进程就是应用程序的运行实例。,1)什么是进程?,一个应用程序可以运行一个或多个进程。多任务就是指操作系统可以同时运行多个进程。,16.1.1 多任务、进程和线程,2)什么是线程?,一个线程可以

3、执行程序的任意部分的代码,即使这部分代码被另一个线程并发地执行。,线程是Windows95/NT操作系统分时调度中分配CPU时间的基本单位。,一个进程可以有一个或多个线程,其中一个是主线程。,一个进程的所有线程共享它的虚拟地址空间、全局变量和操作系统资源。,16.1.1 多任务、进程和线程,3)进程与线程的关系?,16.2 线程的种类,线程有两种,用户界面线程,工作者线程,MFC应用程序通过调用AfxBeginThread函数并给定不同的参数来自动创建两种线程,而不需要程序自己创建, AfxBeginThread函数的具体说明在16.3.1中。,16.16.1 MFC中的线程类,1. MFC应

4、用程序中的线程可由对象CWinThread表示,CWinThread类派生自CcmdTarget类;,16. CWinThread对象代表在一个应用程序内运行的线程;,3. CWinThread对象允许一个应用程序拥有多个线程;,4. CWinThread对象支持两种线程类型:用户界面线程和工作者线程;,16.16.1 MFC中的线程类,5. 用户界面线程可以由CWinThread类派生,也可以是CWinApp类或其派生类。但为安全起见,应由CWinThread类派生。,6. 任何使用MFC的线程必须由MFC创建,创建一个线程必须调用AfxBeginThread函数。,7. CWinThrea

5、d类的数据成员即成员函数见表2-1。,16.16.2 用户界面线程(UI),1) 用户界面线程拥有自己的消息循环来处理界面消息,具有收发消息的功能,处理从消息队列取得的消息;,2) 用户界面线程通常要与用户交互;,3) 用户界面线程可由CWinApp类派生(注:CWinApp类由CWinThread类派生),也可以由CWinThread类直接派生。,4) 一个应用程序的主线程通常由CWinApp类派生,主线程应该是用户界面线程。,16.16.3 工作者线程,1) 工作者线程没有自己的消息循环,一般用来完成后台的工作,如后台计算、打印、与其它设备的串行数据通信等,这些工作的共同特点就是耗时。,2

6、) 为了不影响主线程与用户的交互,通常耗时的工作交给工作者线程来完成;,3) 工作者线程可由CWinThread类直接派生。,16.3 线程的创建、启动和终止,16.3.1 线程的创建,线程的创建由AfxBeginThread函数完成。,AfxBeginThread函数有两种调用格式,可以根据需要分别用来创建工作者线程和用户界面线程。,一、AfxBeginThread函数用来创建工作者线程的调用格式:,16.3.1 线程的创建,CWinThread* AfxBeginThread( AFX_THREADPROC pfnThreadProc, LPVOID pParam, int nPriori

7、ty = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );,pfnThreadProc:线程函数的地址,该参数不能设置为NULL,线程函数必须定义成全局函数或者类的静态成员函数。,例如: UINT myThreadFunc(LPVOID lparam) 或者 class A public: static UINT _stdcall myThreadFunc(LPVOID lparam); ,1.参数说明:,16

8、.3.1 线程的创建,pParam:要传递给线程函数的参数;,nPriority:要启动的线程的优先级,默认优先级为THREAD_PRIORITY_NORMAL(普通优先级),关于线程优先级的详细说明见16.4.2;,nStackSize:新线程的堆栈大小,如果设置为0,则使用默认大小,在应用程序中一般情况下线程的默认堆栈大小为1M;,16.3.1 线程的创建,lpSecurityAttrs :指向SECURITY_ATTRIBUTES结构的指针,结构中指定了线程的安全属性。如果为NULL,则与 创建它的线程的安全属性相同。,dwCreateFlags:线程创建标志,该参数指定线程的初始状态,

9、它可以被指定为下列标志: 0:线程在创建后立即执行 CREATE_SUSPENDED:线程在创建后立即挂起,16.3.1 线程的创建,16.函数返回值的说明:,函数AfxBeginThread返回指向CWinThread类的指针。,16.3.1 线程的创建,3.创建工作者线程的过程:,利用函数AfxBeginThread创建工作者线程需要两步:,1) 编写线程控制函数;,2) 调用函数AfxBeginThread启动线程,将线程控制函数的地址作为第一个参数,线程控制函数的参数作为第二个参数赋给AfxBeginThread函数,,16.3.1 线程的创建,在应用程序中,可以创建一个指向CWinT

10、hread类的指针,用来保存AfxBeginThread函数的返回值,即AfxBeginThread函数创建成功的线程类CWinThread, 以便创建好的线程进行控制,例如:,4.其它说明:,16.3.1 线程的创建,CWinThread* pWinThread; pWinThread=AfxBeginThread( ControlFunction, pParam, THREAD_PRIORTY_NORMAL, 0, CREATE_SUSPENDED, NULL);,16.3.1 线程的创建,pWinThread-m_bAutoDelete=false; delete pWinThread;

11、,这时应注意:,即要将CWinThread类的数据成员m_bAutoDelete设为false,并且在退出进程前,将指向线程类CWinThread的指针pWinThread删除。,16.3.1 线程的创建,二、AfxBeginThread函数用来创建用户界面线程的调用格式:,CWinThread* AfxBeginThread( CRuntimeClass* pThreadClass, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUT

12、ES lpSecurityAttrs = NULL );,16.3.1 线程的创建,pfnThreadProc: 指向CRuntimeClass类的指针。 其它参数的说明与前面相同。,1.参数说明:,16.创建用户界面线程的过程:,1) 从CWinThread类派生一个新类,派生类必须用DECLARE_DYNCREATE和IMPLEMENT_DYNCREATE宏来声明和实现;,16.3.1 线程的创建,2) 重载派生类的InitInstance、ExitInstance等函数,在InitInstance函数中添加代码。,四、通过例题演示利用AfxBeginThread函数创建工作者线程和用户界

13、面线程的过程。,16.3.1 线程的创建,三、关于CreateThread( )函数的一些说明: 见附带文件2。,16.3.2 线程的启动,线程启动时的初始状态可以通过AfxBeginThread( )函数的dwCreateFlags参数指定。如下:,0:线程在创建后立即执行; CREATE_SUSPENDED:线程在创建后立即挂起;,所谓挂起就是暂停线程的执行。,16.3.3 线程的终止,遇到以下情况时,线程终止执行:,1.线程控制函数返回(即执行了return语句)。,16.线程自身调用函数ExitThread( )函数即终止自己。该函数的原型如下: VOID WINAPI ExitThr

14、ead(DWORD dwExitCode ); 该函数通过参数dwExitCode给线程设置退出码后,即终止线程的执行。,16.3.3 线程的终止,3.同一进程或其他进程的线程调用TerminateThread函数,其原型为: BOOL TerminateThread( HANDLE hThread, DWORD dwExitCode );,该函数用来结束由hThread参数指定的线程,并把dwExitCode设成该线程的退出码。当某个线程不再响应时,我们可以用其他线程调用该函数来终止这个不响应的线程。,16.3.3 线程的终止,4.包含线程的进程被终止,如其它进程调用TerminatePro

15、cess函数终止进程的执行,或进程自身调用ExitProcess函数终止自身的执行。,BOOL WINAPI TerminateProcess( HANDLE hProcess, UINT uExitCode );,TerminateProcess函数的原型为:,VOID WINAPI ExitProcess( UINT uExitCode );,ExitProcess函数的原型为:,16.3.3 线程的终止,5. 调用全局函数AfxEndThread终止进程;,注意:最好使用第1种方式终止线程,第24种方式都不宜采用。,16.4.1 线程的运行状态的设置,16.4 线程的操作和管理,1.当参

16、数dwCreateFlags置为0时,调用AfxBeginThread函数创建的线程一启动就立即执行。这时,如果想暂停该线程的执行,可调用其成员函数SuspendedThread( )函数将自身挂起。,AfxEndThread函数的dwCreateFlags参数是决定线程在创建时的运行状态的。,16.4.1 线程的运行状态的设置,16.当参数dwCreateFlags置为CREATE_SUSPENDED时,调用AfxBeginThread函数创建的线程一启动就挂起,暂停执行。这时,如果想继续执行线程,可调用成员函数ResumeThread( )函数唤醒被挂起的线程。,被挂起的线程不能调用此函数唤醒自身,必须由一个未被挂起的处于运行状态的线程调用此函数来取消挂起。,注意:,16.4.2 线程的优先级,一、 Windows操作系统是根据进程和线程的优先级来确定它们的排队顺序并分配CPU时间的,所以对于进程和线程在

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

当前位置:首页 > 高等教育 > 大学课件

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