vc多线程编程PPT格式课件下载.pptx

上传人:b****1 文档编号:14309958 上传时间:2022-10-22 格式:PPTX 页数:46 大小:488.04KB
下载 相关 举报
vc多线程编程PPT格式课件下载.pptx_第1页
第1页 / 共46页
vc多线程编程PPT格式课件下载.pptx_第2页
第2页 / 共46页
vc多线程编程PPT格式课件下载.pptx_第3页
第3页 / 共46页
vc多线程编程PPT格式课件下载.pptx_第4页
第4页 / 共46页
vc多线程编程PPT格式课件下载.pptx_第5页
第5页 / 共46页
点击查看更多>>
下载资源
资源描述

vc多线程编程PPT格式课件下载.pptx

《vc多线程编程PPT格式课件下载.pptx》由会员分享,可在线阅读,更多相关《vc多线程编程PPT格式课件下载.pptx(46页珍藏版)》请在冰豆网上搜索。

vc多线程编程PPT格式课件下载.pptx

,第10章多线程编程,6,第10章多线程编程,7,第10章多线程编程,选择【Spy|Processes】菜单命令,在打开的窗口中可以看到操作系统管理的所有进程的信息,如下图所示。

8,10.1.3MFC对多线程编程的支持,多线程的操作由MFC类CWinThread及其派生类支持,该类的对象代表进程中执行的线程。

下图给出了MFC应用程序框架结构类的继承关系。

第10章多线程编程,9,从上图可以看出,MFC应用程序类CWinApp是由CWinThread类派生而来的,用于启动进程的主线程。

另外,MFC还提供了支持多线程同步的同步类,如CEvent、CCriticalSection、CSemaphore和CMutex等。

也提供了线程同步辅助类CSingleLock和CMutiLock。

第10章多线程编程,10,10.2线程的创建,第10章多线程编程,MFC中有两类线程,分别称之为工作者线程和用户界面线程。

两者的主要区别在于:

工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环。

11,10.2.1创建工作者线程,创建一个工作者线程,首先需要编写一个希望与应用程序的其余部分并行运行的自定义函数,该函数称为线程函数。

然后,在程序中合适的地方调用全局函数AfxBeginThread()创建线程,启动线程函数。

第10章多线程编程,12,1.定义线程函数线程函数的固定形式:

UINTFunctionName(LPVOIDpParam)FunctionName是用户自定义的函数名,LPVOID表示指向空类型的指针,相当于void*,必要时需要把这个指针转换成所需要的类型。

函数的返回值将作为线程的结束码,线程函数结束后线程就自动终止。

函数的返回值如果为0,表示线程函数正常结束。

第10章多线程编程,13,2启动线程函数CWinThread*AfxBeginThread(AFX_THREADPROCpfnThreadProc,LPVOIDpParam,intnPriority=THREAD_PRIORITY_NORMAL,UINTnStackSize=0,DWORDdwCreateFlags=0,LPSECURITY_ATTRIBUTESlpSecurityAttrs=NULL);

pfnThreadProc是一个指向线程函数的指针,参数pParam的类型与线程函数的参数类型完全一致,该参数为启动线程时传递给线程函数的入口参数。

其他几个参数用于设置线程优先级、线程的堆栈大小、创建时是否立即运行及线程的安全属性,这4个参数通常使用默认值。

第10章多线程编程,14,【例10.2】编写一个创建工作线程的单文档应用程序Li10_2,当执行【计算素数】菜单命令时启动一个工作线程,计算11000000之间素数的个数。

第10章多线程编程,15,第10章多线程编程,10.2.2创建用户界面线程用户界面线程通常用来处理用户输入并响应各种事件和消息,它是通过自己的消息泵获取从系统接收到的消息。

MFC将为该线程增加一个消息循环,以便能够处理收到的消息。

创建用户界面线程的过程与创建一个工作者线程的过程完全不同。

一个工作者线程用由一个线程函数代表,但一个用户界面线程的行为由CWinThread类的派生类来控制。

16,第10章多线程编程,创建用户界面线程的AfxBeginThread()函数:

CWinThread*AfxBeginThread(CRuntimeClass*pThreadClass,intnPriority=THREAD_PRIORITY_NORMAL,UINTnStackSize=0,DWORDdwCreateFlags=0,LPSECURITY_ATTRIBUTESpSecurityAttrs=NULL);

pThreadClass指向一个CRuntimeClass对象,该对象是用RUNTIME_CLASS宏从CWinThread的派生类创建的。

其他参数的含义与前述的函数AfxBeginThread()一样。

17,第10章多线程编程,在程序中创建一个用户界面线程:

AfxBeginThread(RUNTIME_CLASS(class_name);

实参class_name是CWinThread的派生类的名字。

18,第10章多线程编程,【例10.3】在基于对话框的应用程序Li10_3中创建用户界面线程。

每单击一次“用户界面线程”按钮,都会弹出一个线程对话框,在任何一个线程对话框内按下鼠标左键,都会弹出一个消息框,效果如下图所示。

19,10.3线程的控制,第10章多线程编程,线程控制是指控制线程的状态。

从以下几个方面控制线程:

创建一个线程、终止一个线程、挂起一个正运行的线程、激活一个暂停运行的线程、读取和设置线程的优先级、使当前线程等待一定的时间及放弃一个或多个运行时间片等。

20,10.3.1终止一个线程,第10章多线程编程,当一个工作者线程的线程函数执行一个返回语句或者调用AfxEndThread()成员函数时,这个工作者线程就终止。

AfxEndThread()函数原型:

voidAfxEndThread(UNITnExitCode);

参数nExitCode表示线程的32位退出码。

21,10.3.2悬挂和恢复线程,第10章多线程编程,CWinThread类中包含线程悬挂和恢复的成员函数。

悬挂就是挂起或暂定线程的运行。

悬挂函数:

DWORDCWinThread:

SuspendThread();

恢复就是激活一个暂停运行的线程,即被悬挂的线程。

恢复函数:

ResumeThread();

22,10.3.3线程的优先级,第10章多线程编程,使用CWinThread:

SetThreadPriority函数设置线程的相对优先级:

使用CWinThread:

GetThreadPriority函数获取线程的相对优先级:

intGetThreadPriority(HANDLEhThread);

参数hThread是要设置或获取优先级线程的句柄,参数nPriority就是要设置的优先级。

BOOLSetThreadPriority(HANDLEhThread,intnPriority);

23,第10章多线程编程,【例10.4】在基于对话框的应用程序Li10_4中,首先创建两个工作线程,分别控制滑动条及进度条的走动,然后对线程进行控制,包括挂起、唤醒、停止及优先级的设置。

程序运行界面如下图所示。

24,第10章多线程编程,10.4线程间的通信,一般可以使用全局变量进行通信和自定义消息进行通信。

10.4.1使用全局变量进行通信对于标准类型的全局变量,建议使用volatile修饰符,它告诉编译器无需对该变量作任何的优化,即无需将它放到一个寄存器中,并且该值可被外部改变。

如果线程间所需传递的信息较复杂,可以定义一个结构,通过传递指向该结构的指针进行传递信息。

接着让线程监视这个变量,当这个变量符合一定的条件时,表示线程应该终止。

25,第10章多线程编程,10.4.2使用自定义消息进行通信使用Windows消息来进行通讯,首先需要定义一个自定义消息,然后,需要时在一个线程中调用全局函数:

PostMessage()向另一个线程发送自定义消息。

PostMessage()函数的原型为:

BOOLPostMessage(HWNDhwnd,UINTMsg,WPARAMwParam,LPARAMlParam);

hwnd为发送窗口的句柄,Msg为消息的ID,wParam和lParam为消息的相关参数。

26,第10章多线程编程,【例10.5】完善例10.2中的Li10_2,Calculateprime()线程函数执行完后,向主线程发送消息,主线程收到该消息后再显示计算结果。

27,第10章多线程编程,使隶属于同一进程的各线程协调一致地工作称为线程的同步。

在多线程的环境里,需要对线程进行同步。

常用的同步对象有临界区、互斥、信号量和事件。

10.5线程间的同步,28,第10章多线程编程,当多个线程访问临界区时,可以使用临界区对象,即CCriticalSection类的对象。

临界区是一个独占性共享资源,任一时刻只有一个线程可以拥有临界区。

10.5.1使用CCriticalSection类,29,第10章多线程编程,CCriticalSection类的用法有两种:

方法一:

单独使用CCriticalSection对象步骤如下:

(1)定义CCriticalSection类的一个全局对象(以使各个线程均能访问),如:

CCriticalSectioncritical_section;

CCriticalSection类的构造函数只有一种形式,即不带任何参数,如上述代码所示。

30,第10章多线程编程,

(2)在访问临界区之前,调用CCriticalSection类的成员Lock()获得临界区。

critical_section.Lock();

其中Lock()的原型:

BOOLLock();

在线程中调用该函数来使线程获得它所请求的临界区。

如果此时没有其他线程占有临界区,则调用Lock()的线程获得临界区;

否则,线程即将挂起,并放入到一个系统队列中等待,直到当前拥有临界区的线程释放了临界区时为止。

31,第10章多线程编程,(3)在本线程中访问临界区中的共享资源。

(4)访问临界区完毕后,使用CCriticalSection的成员函数UnLock()来释放临界区。

critical_section.UnLock();

32,第10章多线程编程,方法二:

与同步辅助类CSingleLock或CMutiLock类一起使用,步骤如下(以类CSingleLock为例):

(1)定义CCriticalSection类的一个全局对象critical_section:

(2)在访问临界区之前,定义CSingleLock类的一个对象,并将critical_section的地址传送给构造函数,如:

CSingleLocksinglelock(&

critical_section);

33,第10章多线程编程,(3)使用CSingleLock类的成员函数Lock()请求获得临界区。

singlelock.Lock();

其中,CSingleLock类的成员函数Lock()原型:

BOOLLock(DWORDdwTimeOut=INFINITE

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 军事

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1