C++课件-第16章-多任务与多线程编程.ppt
《C++课件-第16章-多任务与多线程编程.ppt》由会员分享,可在线阅读,更多相关《C++课件-第16章-多任务与多线程编程.ppt(87页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、本章主要教学内容本章主要教学内容l进程与线程进程与线程l线程的种类与线程的种类与MFCMFC同步类同步类l线程的使用线程的使用l线程的同步及常用的同步对象线程的同步及常用的同步对象第第1616章章 多任务与多线程编程多任务与多线程编程16.1 16.1 程序、进程和线程概述程序、进程和线程概述16.2 16.2 线程的种类线程的种类16.3 16.3 线程的创建、启动和终止线程的创建、启动和终止16.4 16.4 线程的操作和管理线程的操作和管理16.5 16.5 在在VC+VC+环境中使用同步对象环境中使用同步对象16.6 16.6 本章小结本章小结16.7 16.7 思考与练习思考与练习1
2、6.1 16.1 程序、进程和线程概程序、进程和线程概述述16.1.1 16.1.1 多任务、进程和线多任务、进程和线程程1 1Windows3.xWindows3.x的协同多任务的协同多任务 如何解决后台工作和对用户的随时响应之间的如何解决后台工作和对用户的随时响应之间的协同?详见教材协同?详见教材P27P27。 Windows3.x Windows3.x对应用程序的对应用程序的CPUCPU控制权的调度方式:控制权的调度方式: 协同式多任务。其特点详见教材协同式多任务。其特点详见教材P27P27。 补充知识:什么是模态对话框和非模态对话框?补充知识:什么是模态对话框和非模态对话框? 见附带文
3、件见附带文件1 1。16.Windows95/NT16.Windows95/NT的抢先式多任务的抢先式多任务 Windows95/NT Windows95/NT对应用程序的对应用程序的CPUCPU控制权的控制权的 调度方式:抢先式多任务。其特点详见教材调度方式:抢先式多任务。其特点详见教材P28P28。16.1.1 16.1.1 多任务、进程和线程多任务、进程和线程3 3进程与线程进程与线程16.1.1 16.1.1 多任务、进程和线多任务、进程和线程程 进程由私有虚拟地址空间、代码、数据和进程由私有虚拟地址空间、代码、数据和其它操作系统资源(如进程创建的文件、同步其它操作系统资源(如进程创建
4、的文件、同步对象等)组成。对象等)组成。 进程就是应用程序的运行实例。进程就是应用程序的运行实例。1)1)什么是进程?什么是进程? 一个应用程序可以运行一个或多个进程。多任一个应用程序可以运行一个或多个进程。多任务就是指操作系统可以同时运行多个进程。务就是指操作系统可以同时运行多个进程。 16.1.1 16.1.1 多任务、进程和线多任务、进程和线程程2)2)什么是线程?什么是线程? 一个线程可以执行程序的任意部分的代码,一个线程可以执行程序的任意部分的代码,即使这部分代码被另一个线程并发地执行。即使这部分代码被另一个线程并发地执行。 线程是线程是Windows95/NTWindows95/N
5、T操作系统分时调度中分操作系统分时调度中分配配CPUCPU时间的基本单位。时间的基本单位。 一个进程可以有一个或多个线程,其中一个一个进程可以有一个或多个线程,其中一个是主线程。是主线程。 一个进程的所有线程共享它的虚拟地址空间一个进程的所有线程共享它的虚拟地址空间、全局变量和操作系统资源。、全局变量和操作系统资源。16.1.1 16.1.1 多任务、进程和线多任务、进程和线程程3)3)进程与线程的关系?进程与线程的关系?16.2 16.2 线程的种类线程的种类线程有两种线程有两种用户界面线程用户界面线程工作者线程工作者线程 MFC MFC应用程序通过调用应用程序通过调用AfxBeginThr
6、eadAfxBeginThread函数并给定函数并给定不同的参数来自动创建两种线程,而不需要程序自己不同的参数来自动创建两种线程,而不需要程序自己创建,创建, AfxBeginThreadAfxBeginThread函数的具体说明在函数的具体说明在16.3.116.3.1中。中。16.16.1 MFC16.16.1 MFC中的线程中的线程类类1.1. MFC MFC应用程序中的线程可由对象应用程序中的线程可由对象CWinThreadCWinThread表示,表示,CWinThreadCWinThread类派生自类派生自CcmdTargetCcmdTarget类;类;16.16. CWinThr
7、ead CWinThread对象代表在一个应用程序内运行的线程对象代表在一个应用程序内运行的线程;3.3. CWinThread CWinThread对象允许一个应用程序拥有多个线程;对象允许一个应用程序拥有多个线程;4.4. CWinThread CWinThread对象支持两种线程类型:用户界面线程对象支持两种线程类型:用户界面线程和工作者线程和工作者线程; ;16.16.1 MFC16.16.1 MFC中的线程中的线程类类5.5. 用户界面线程可以由用户界面线程可以由CWinThreadCWinThread类派生,也类派生,也可以是可以是CWinAppCWinApp类或其派生类。但为安全
8、起见,类或其派生类。但为安全起见,应由应由CWinThreadCWinThread类派生。类派生。6.6. 任何使用任何使用MFCMFC的线程必须由的线程必须由MFCMFC创建,创建一个创建,创建一个线程必须调用线程必须调用AfxBeginThreadAfxBeginThread函数。函数。7.7. CWinThread CWinThread类的数据成员即成员函数见表类的数据成员即成员函数见表2-12-1。16.16.2 16.16.2 用户界面线程(用户界面线程(UIUI)1)1) 用户界面线程拥有自己的消息循环来处理界面消息,用户界面线程拥有自己的消息循环来处理界面消息,具有收发消息的功能
9、,处理从消息队列取得的消息;具有收发消息的功能,处理从消息队列取得的消息;2)2) 用户界面线程通常要与用户交互;用户界面线程通常要与用户交互;3)3) 用户界面线程可由用户界面线程可由CWinAppCWinApp类派生类派生( (注:注:CWinAppCWinApp类由类由CWinThreadCWinThread类派生类派生) ),也可以由,也可以由CWinThreadCWinThread类直接派生。类直接派生。4)4) 一个应用程序的主线程通常由一个应用程序的主线程通常由CWinAppCWinApp类派生,主类派生,主线程应该是用户界面线程。线程应该是用户界面线程。16.16.3 16.1
10、6.3 工作者线工作者线程程1)1) 工作者线程没有自己的消息循环,一般用来完成工作者线程没有自己的消息循环,一般用来完成后台的工作,如后台计算、打印、与其它设备的串后台的工作,如后台计算、打印、与其它设备的串行数据通信等,这些工作的共同特点就是耗时。行数据通信等,这些工作的共同特点就是耗时。2)2) 为了不影响主线程与用户的交互,通常耗时的工为了不影响主线程与用户的交互,通常耗时的工作交给工作者线程来完成;作交给工作者线程来完成;3)3) 工作者线程可由工作者线程可由CWinThreadCWinThread类直接派生。类直接派生。16.3 16.3 线程的创建、启动和终线程的创建、启动和终止
11、止16.3.1 16.3.1 线程的创建线程的创建线程的创建由线程的创建由AfxBeginThreadAfxBeginThread函数完成。函数完成。 AfxBeginThread AfxBeginThread函数有两种调用格式,可以根据函数有两种调用格式,可以根据需要分别用来创建工作者线程和用户界面线程。需要分别用来创建工作者线程和用户界面线程。一、一、AfxBeginThreadAfxBeginThread函数用来创建工作者线程的函数用来创建工作者线程的调用格式:调用格式:16.3.1 16.3.1 线程的创建线程的创建CWinThread* AfxBeginThread( AFX_THR
12、EADPROC pfnThreadProc, LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL ); pfnThreadProc:pfnThreadProc:线程函数的地址线程函数的地址, ,该参数不能设该参数不能设置为置为NULL,NULL,线程函数必须定义成全局函数或者类线程函数必须定义成全局函数或者类的静态成员函数。的静态成员函数。例如例如:UINT
13、 myThreadFunc(LPVOID lparam)或者或者class Apublic: static UINT _stdcall myThreadFunc(LPVOID lparam);1.1.参数说明参数说明: :16.3.1 16.3.1 线程的创线程的创建建 pParam: pParam:要传递给线程函数的参数;要传递给线程函数的参数; nPriority:nPriority:要启动的线程的优先级要启动的线程的优先级, ,默认优先级默认优先级为为THREAD_PRIORITY_NORMAL(THREAD_PRIORITY_NORMAL(普通优先级普通优先级),),关于关于线程优先级
14、的详细说明见线程优先级的详细说明见16.4.216.4.2;nStackSize:nStackSize:新线程的堆栈大小新线程的堆栈大小, ,如果设置为如果设置为0,0,则使则使用默认大小用默认大小, ,在应用程序中一般情况下线程的默认堆在应用程序中一般情况下线程的默认堆栈大小为栈大小为1M1M;16.3.1 16.3.1 线程的创线程的创建建 lpSecurityAttrslpSecurityAttrs : :指向指向SECURITY_ATTRIBUTESSECURITY_ATTRIBUTES结结构的指针,结构中指定了线程的安全属性。如果构的指针,结构中指定了线程的安全属性。如果为为NULL
15、NULL,则与,则与 创建它的线程的安全属性相同。创建它的线程的安全属性相同。 dwCreateFlags:dwCreateFlags:线程创建标志线程创建标志, ,该参数指定线程该参数指定线程的初始状态,它可以被指定为下列标志:的初始状态,它可以被指定为下列标志: 0 0:线程在创建后立即执行:线程在创建后立即执行 CREATE_SUSPENDED:CREATE_SUSPENDED:线程在创建后立即挂起线程在创建后立即挂起16.3.1 16.3.1 线程的创线程的创建建16.16.函数返回值的说明函数返回值的说明: :函数函数AfxBeginThreadAfxBeginThread返回指向返
16、回指向CWinThreadCWinThread类的指针。类的指针。16.3.1 16.3.1 线程的创线程的创建建3.3.创建工作者线程的过程创建工作者线程的过程: :利用函数利用函数AfxBeginThreadAfxBeginThread创建工作者线程需要两步:创建工作者线程需要两步:1) 1) 编写线程控制函数;编写线程控制函数;2) 2) 调用函数调用函数AfxBeginThreadAfxBeginThread启动线程,将线程控启动线程,将线程控制函数的地址作为第一个参数,线程控制函数的参制函数的地址作为第一个参数,线程控制函数的参数作为数作为第二个参数赋给第二个参数赋给AfxBegin
17、ThreadAfxBeginThread函数,函数,16.3.1 16.3.1 线程的创线程的创建建 在应用程序中,可以创建一个指向在应用程序中,可以创建一个指向CWinThreadCWinThread类类的指针,用来保存的指针,用来保存AfxBeginThreadAfxBeginThread函数的返回值,即函数的返回值,即AfxBeginThreadAfxBeginThread函数创建成功的线程类函数创建成功的线程类CWinThreadCWinThread,以便创建好的线程进行控制,例如:以便创建好的线程进行控制,例如:4.4.其它说明其它说明: :16.3.1 16.3.1 线程的创线程的
18、创建建CWinThreadCWinThread* * pWinThread; pWinThread;pWinThread=AfxBeginThread(pWinThread=AfxBeginThread( ControlFunction,ControlFunction, pParam, pParam, THREAD_PRIORTY_NORMAL, THREAD_PRIORTY_NORMAL, 0, 0, CREATE_SUSPENDED, CREATE_SUSPENDED, NULL); NULL);16.3.1 16.3.1 线程的创线程的创建建pWinThread-m_bAutoDelet
19、e=false;delete pWinThread;这时应注意这时应注意: : 即要将即要将CWinThreadCWinThread类的数据成员类的数据成员m_bAutoDeletem_bAutoDelete设为设为false,false,并且在退出进程前,将指向线程类并且在退出进程前,将指向线程类CWinThreadCWinThread的指针的指针pWinThreadpWinThread删除。删除。16.3.1 16.3.1 线程的创线程的创建建二、二、AfxBeginThreadAfxBeginThread函数用来创建用户界面线程函数用来创建用户界面线程的调用格式:的调用格式:CWinTh
20、read* AfxBeginThread( CRuntimeClass* pThreadClass, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );16.3.1 16.3.1 线程的创线程的创建建 pfnThreadProc: pfnThreadProc: 指向指向CRuntimeClassCRuntimeClass类的指针。类的指针。 其它参数的说明与前面相同。其它参数的说明
21、与前面相同。1.1.参数说明参数说明: :16.16.创建用户界面线程的过程创建用户界面线程的过程: :1) 1) 从从CWinThreadCWinThread类派生一个新类,派生类必须类派生一个新类,派生类必须用用DECLARE_DYNCREATEDECLARE_DYNCREATE和和IMPLEMENT_DYNCREATEIMPLEMENT_DYNCREATE宏宏来声明和实现;来声明和实现;16.3.1 16.3.1 线程的创线程的创建建2) 2) 重载派生类的重载派生类的InitInstanceInitInstance、ExitInstanceExitInstance等等函数,在函数,在I
22、nitInstanceInitInstance函数中添加代码。函数中添加代码。四、四、通过例题演示利用通过例题演示利用AfxBeginThreadAfxBeginThread函数创建函数创建工作者线程和用户界面线程的过程。工作者线程和用户界面线程的过程。16.3.1 16.3.1 线程的创线程的创建建三、三、关于关于CreateThread( )CreateThread( )函数的一些说明:函数的一些说明: 见附带文件见附带文件2 2。16.3.2 16.3.2 线程的启动线程的启动 线程启动时的初始状态可以通过线程启动时的初始状态可以通过AfxBeginThread( )AfxBeginTh
23、read( )函数的函数的dwCreateFlagsdwCreateFlags参数指定。如下:参数指定。如下:0 0:线程在创建后立即执行;:线程在创建后立即执行;CREATE_SUSPENDED:CREATE_SUSPENDED:线程在创建后立即挂起;线程在创建后立即挂起;所谓挂起就是暂停线程的执行。所谓挂起就是暂停线程的执行。16.3.3 16.3.3 线程的终线程的终止止遇到以下情况时,线程终止执行:遇到以下情况时,线程终止执行:1.1.线程控制函数返回(即执行了线程控制函数返回(即执行了returnreturn语句)。语句)。16.16.线程自身调用函数线程自身调用函数ExitThre
24、ad( )ExitThread( )函数函数即终止自己即终止自己。该函数的原型如下:该函数的原型如下: VOID WINAPI ExitThread(DWORD dwExitCode );VOID WINAPI ExitThread(DWORD dwExitCode ); 该函数通过参数该函数通过参数dwExitCodedwExitCode给线程设置退出码后,给线程设置退出码后,即终止线程的执行。即终止线程的执行。16.3.3 16.3.3 线程的终线程的终止止3.3.同一进程或其他进程的线程调用同一进程或其他进程的线程调用TerminateThreadTerminateThread函数,其原
25、型为:函数,其原型为: BOOL TerminateThread( BOOL TerminateThread( HANDLE hThread, HANDLE hThread, DWORD dwExitCode DWORD dwExitCode ); ); 该函数用来结束由该函数用来结束由hThreadhThread参数指定的线程,并把参数指定的线程,并把dwExitCodedwExitCode设成该线程的退出码。当某个线程不再响应时,设成该线程的退出码。当某个线程不再响应时,我们可以用其他线程调用该函数来终止这个不响应的线程。我们可以用其他线程调用该函数来终止这个不响应的线程。 16.3.3
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 课件 16 任务 多线程 编程
限制150内