欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    网络编程实用教程第7-8章-多线程编程.ppt

    • 资源ID:6016917       资源大小:203KB        全文页数:62页
    • 资源格式: PPT        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    网络编程实用教程第7-8章-多线程编程.ppt

    网络编程实用教程,第7章 WinSock的多线程编程,本章内容:WinSock需要多线程编程的原因:Win32操作系统下的多进程多线程机制、多线程机制在网络编程中的应用和Visual C+6.0对多线程网络编程的支持。分析了 MFC 支持的两种线程,给出了创建MFC的工作线程、创建并启动用户界面线程和终止线程的步骤。,7.1 WinSock为什么需要多线程编程,7.1.1 WinSock的两种输入输出模式,如前所述,WinSock在进行输入输出的时候,可以使用两种工作模式:“阻塞”模式:又称为同步模式“非阻塞”模式:又称为异步模式 工作在“阻塞”模式下的套接字被称为阻塞套接字,而工作在“非阻塞”模式下的套接字称为非阻塞套接字。,7.1.2 两种模式的优缺点及解决方法,“阻塞”与“非阻塞”模式的优点和缺点:阻塞套接字的I/O操作工作情况比较确定,即调用、等待、返回。大部分情况下,I/O操作都能成功地完成,只是花费了等待的时间,容易编程;需要建立多个套接字连接来为多个客户服务的时候,或在数据的收发量不均匀的时候,或在输入输出的时间不确定的时候,阻塞套接字的性能低下,甚至无能为力。,使用非阻塞套接字,需要编写更多的代码,因为必须恰当地把握调用I/O函数的时机,尽量减少无功而返的调用,还必须详加分析每个Winsock调用中收到的错误,采取相应的对策,这种I/O操作的随机性使得非阻塞套接字显得难于操作。所以必须采取适当的对策,让阻塞和非阻塞套接字能够满足各种场合的要求。对于非阻塞工作模式:引入了五种“套接字I/O模型”。阻塞的工作模式,则引入了多线程机制。,7.2 Win32操作系统下的多进程多线程机制,7.2.2 Win32 OS支持多线程,应用程序、进程及线程的关系 DOS是单用户单任务的。Win32操作系统是多任务的,并且支持一个进程中有多个线程。一个线程(thread)是进程内的一条执行路径,是一个应用程序中的一条可执行路径。一个进程中至少要有一个线程,称为主线程。当启动了一个应用程序时,操作系统将为它创建了一个进程,同时创建该进程的主线程,并开始执行主线程。主线程可以创建并启动其他辅助线程,由主线程创建的线程又可以创建并启动更多的线程。,7.2.2 Win32 OS支持多线程,单CPU分时地运行进程中的各个线程,7.2.3 多线程机制在网络编程中的应用,如果一个应用程序,有多个任务需要同时进行处理,则适合使用多线程机制。对于网络上客户机软件:采用多线程,能克服在单线程的编程模式下,由于阻塞等待而产生的客户程序就不能及时响应用户的操作命令的问题。对于网络上服务器软件:采用多线程的编程技术,能更好地为多个客户服务。对于一个客户:采用多线程机制也能大大提高应用程序的运行效率。网络在线实时监控软件:,7.3 VC6.0对多线程网络编程的支持,VC6.0环境下,两种开发程序的方法:直接使用Win32 API来编写Win32 应用程序利用MFC 基础类库编写 C+风格的应用程序。在这两种Windows应用程序的开发方式下,多线程的编程原理是一致的。,7.3.1 MFC支持的两种线程,微软的基础类库MFC提供了对于多线程应用程序的支持。在MFC中,线程分为两种:用户接口线程:(user-interface thread),或称用户界面线程;工作线程:(the worker thread),这两类线程可以满足不同任务的处理需求。,1、用户接口线程 作用:用于处理用户的输入,响应用户产生的消息。MFC为用户接口线程提供了一个消息泵。同时包含一个消息循环,以应对各种事件。MFC应用程序的CWinApp类对象是一个典型的用户接口线程 在MFC应用程序中,CWinThread是用户接口线程的基类,CWinApp就是从CWinThread 类派生出来的,编写用户接口线程候,也需要从CWinThread 类派生。,2工作线程 工作线程(worker thread),适用于处理那些不要求用户输入并且比较消耗时间的其他任务。对用户来说,工作线程运行在后台。这就使得工作线程特别适合去等待一个事件的发生。CWinThread 类同样是工作线程的基类。在编写工作线程的时候,可以调用MFC的AfxBeginThread函数,来创建CWinThread对象。,7.3.2 创建MFC的工作线程,利用MFC创建工作线程的步骤:第一步:编程实现控制函数第二步:创建并启动工作线程 一般不必从CWinThread派生一个类。如果需要一个特定版本的 CWinThread 类,也可以去派生;但对于大多数的工作线程是不要求的。可以不作任何修改地使用CWinThread类。,7.3.2 创建MFC的工作线程,1、编程实现控制函数 一个工作线程对应一个控制函数。线程执行的任务都应编写在控制函数之中,规定了该线程的执行代码,当控制函数执行结束而退出时,线程也就随之终止。编写工作线程的控制函数必须遵守一定的格式,控制函数的原型声明是:UINT ControlFunctionName(LPVOID pParam);pParam是一个数据结构;,7.3.2 创建MFC的工作线程,2创建并启动工作线程(Starting the thread)启动线程:即开始运行它对应的控制函数。在主线程或其他线程中调用AfxBeginThread()函数就可以创建新的线程,并使新线程开始运行。一般将线程的创建者称为新线程的父线程。AfxBeginThread()函数有两个重载的版本,区别在于使用的入口参数不同。,7.3.2 创建MFC的工作线程,CWinThread*AfxBeginThread(AFX_THREADPROC pfnThreadProc,/控制函数的地址 LPVOID pParam,/数据结构的指针,传数据给线程控制函数 int pPriority=THREAD_PRIORITY_NORMAL,/优先级 UINT nStackSize=0,/线程的堆栈大小(缓冲区)DWORD dwCreateFlags=0,/线程的运行状态,是否被挂起 LPSECURITY_ATTTRIBUTES lpSecurityAttrs=NULL/安全属性);后面4个参数为可选参数。,创建工作线程的例子,3、创建工作线程的例子功能:求长度为N的数组Arry的各元素的和。编程实现线程控制函数(1)/首先定义了一个结构:struct int N;/数组元素的个数。double*Arry;/指向一个双精度实数的数组myData;/定义了此结构类型的变量,省略了初始化的代码myData ss;,创建工作线程的例子,(2)/接着定义线程的控制函数。UINT MyCalcFunc(LPVOID pParam)/如果入口参数为空指针,终止线程。if(pPara=NULL)AfxEndThread(MY_NULL_POINTER_ERROR);int N=pPara-N;/数组的元素个数。double*Arry=pPara-Arry;/指向数组的第一个元素。double sum=0;/数组元素之和。for(int i=0;iN;i+)sum+=Arryi;/求和。CString bb;bb.Format(“数组的和是:%d”,sum);/格式化显示字符串。AfxMessageBox(bb);/显示结果。return 0;,改为:pPara,创建工作线程的例子,调用AfxBeginThread()来创建并启动这个线程。将控制函数名和结构变量的地址作为参数传递,其他的参数省略,使用默认值。AfxBeginThread(MyCalcFunc,一旦调用了此函数,线程就被创建,并开始执行线程函数。当数据的计算完成时,函数将停止运行,相应的线程也随即终止。线程拥有的堆栈和其他资源都将释放。CWinThread对象将被删除。,创建工作线程的例子,4创建工作线程的一般模式可以得出创建工作线程的一般模式:定义一个结构myData用于传递数据;工作线程控制函数的框架;UINT MyThreadProc(LPVOID pPara)if(pPara=NULL)AfxEndThread(MY_NULL_POINTER_ERROR);return 1;,创建工作线程的例子,/利用入口参数作某些工作。return 0;/线程成功地完成并返回。在程序的另一个函数中插入以下代码。.myData ss;AfxBeginThread(MyThreadProc,ss);,7.3.3 创建并启动用户界面线程,用户界面线程允许用户使用更多的用户界面对象,如对话框或其他窗口。因此,要使用用户界面线程,需要做更多的工作:创建并启动用户界面线程要经过三个步骤:从CWinThread类派生出自己的线程类;改造这个线程类,使它能够完成用户希望的工作创建并启动用户界面线程。,7.3.3 创建并启动用户界面线程,1、从CWinThread类派生出自己的线程类 要创建一个用户界面线程,首先从CWinThread 类派生出自己的线程类,可借助ClassWizard来完成。2、改造自己的线程类 对这个派生的线程类作以下改造工作:在类的.h头文件中,用DECLARE_DYNCREATE宏来声明这个类(使其支持动态创建);DECLARE_DYNCREATE(class_name),7.3.3 创建并启动用户界面线程,在类的.CPP文件中,用IMPLEMENT_DYNCREATE宏来实现这个类。调用格式是:IMPLEMENT_DYNCREATE(class_name,base_class_name)两个参数分别是参数是线程类名和它的基类名。,7.3.3 创建并启动用户界面线程,对派生类的改造:这个线程类须重载它的基类的某些成员函数,如该类的InitInstance()成员函数;对于其他成员函数,可以有选择地重载。创建新的用户界面窗口类,并建立线程类与用户界面窗口类的联系。利用类向导为新建的线程类添加控件成员变量,添加响应消息的成员函数,编写实现代码。,7.3.3 创建并启动用户界面线程,WinThread的成员函数包括:,7.3.3 创建并启动用户界面线程,3创建并启动用户界面线程 可以使用MFC提供的AfxBeginThread()函数的另一个创建并启动用户界面线程,调用格式是:CWinThread*AfxBeginThread(CRuntimeClass*pThreadClass,/继承的线程类指针 int pPriority=THREAD_PRIORITY_NORMAL,/优先级 UINT nStackSize=0,/创建线程的堆栈大小 DWORD dwCreateFlags=0,/线程的状态 LPSECURITY_ATTTRIBUTES lpSecurityAttrs=NULL);,7.3.3 创建并启动用户界面线程,4AfxBeginThread()函数所作的工作它创建一个新的用户自己的线程类的对象,该对象继承了CWinThread类的属性。MFC自动调用新线程类的InitInstance()函数,来初始化这个新的线程类对象实例。调用CWinThread:CreateThread函数来开始执行这个线程,并运行RUN函数,进入消息循环。函数返回一个指向新生成的CWinThread对象的指针,可以把它保存在一个变量中,其它线程就可以利用这个指针来访问该线程类的成员变量或成员函数。,7.3.3 创建并启动用户界面线程,线程的消息循环:系统自动地为每一个线程创建一个消息队列,如果线程创建了一个或多个窗口,就必须提供一个消息循环,这个消息循环从线程的消息队列中获取消息,并把它们发送到相应的windows过程。因为系统将消息导向独立的应用程序窗口,所以在开始线程的消息循环之前,线程必须至少创建一个窗口,大多数基于Win32的应用程序包含一个单一的线程,该线程创建了若干窗口。,7.3.4 终止线程,1、正常终止线程工作线程:线程控制函数代码执行完毕用户线程:发送消息到窗口2、提前终止线程利用AfxEndThread(UNIT nExitCode)函数参数为线程的终止代码,该函数应该在线程内部调用;3、终止线程的另一种方法TerminateThread()函数强行终止。,4、获取线程的终止代码Bool GetExitCodeThread(HANDLE hThread,/线程句柄 LPDWORD lpExitCode/接收线程的终止代码)5、设置线程的优先级SetThreadPriority(HANDLE hThread,/线程句柄 int nPriority/优先级水平),多线程编程实例,第8章 Winsock的输入/输出模型,第7章提到,WinSock 在进行输入输出的时候,可以采用阻塞模式或非阻塞模式。使用非阻塞套接字,带有I/O操作的随机性,使非阻塞套接字难于操作,给编程带来困难。为了解决这个问题,对于非阻塞的套接字工作模式,进一步引入了五种“套接字I/O模型”,它们有助于应用程序通过一种异步方式,同时对一个或多个套接字上进行的通信加以管理。,这些模型包括:select(选择)、WSAAsyncSelect(异步选择)、WSAEventSelect(事件选择)、Overlapped I/O(重叠式I/O)Completion port(完成端口)。本章将主要介绍前三种。,不同的Windows平台支持不同的I/O模型。如表8.1:,8.1 select模型,select(选择)模型是Winsock 中最常见的I/O模型。它的中心思想是利用select 函数,实现对多个套接字I/O的管理。利用select函数,可以判断套接字上是否存在数据,或者能否向一个套接字写入数据。只有在条件满足时,才对套接字进行输入输出操作,从而避免无功而返的I/O函数调用,避免频繁产生WSAEWOULDBLOCK错误,使输入输出变得有序。,1select的函数 select的函数原型如下,其中fd_set数据类型,代表着一系列特定套接字的集合。int select(int nfds,fd_set FAR*readfds,fd_set FAR*writefds,fd_set FAR*exceptfds,const struct timeval FAR*timeout);,说明:select函数对readfds、writefds和exceptfds三个集合中指定的套接字进行检查,看是否有数据可读、可写或有带外数据,如果有至少一个套接字符合条件,就立即返回。符合条件的套接字仍在集合中,不符合条件的套接字则被删去。如果一个也没有,则等待。但最多等待timeout所指定的时间,便返回。,2操作套接字集合的宏 在程序中,用select 对套接字进行监视之前,必须先将要检查的套接字句柄分配给某个集合,设置好相应的fd_set结构,再来调用select 函数,便可知道一个套接字上是否正在发生上述的I/O活动。Winsock提供了下列宏操作,专门对fd_set数据类型进行操作FD_CLR(s,*set):从set中删除套接字s。,FD_ISSET(s,*set):检查s是否set集合的一名成员;如答案是肯定的是,则返回TRUE。FD_SET(s,*set):将套接字s加入集合set。FD_ZERO(*set):将set初始化成空集合。其中,参数s是一个要检查的套接字,参数set是一个fd_set集合类型的指针。例如:调用select函数前,可使用 FD_SET宏将指定的套接字加入到fd_read集合中,select函数完成后,可使用FD_ISSET宏,来检查该套接字是否仍在fd_read集合中。,3select模型的操作步骤使用 FD_ZERO宏初始化感兴趣的每一个 fd_set集合。使用 FD_SET宏将要检查的套接字句柄添加到感兴趣的每个 fd_set集合中,相当在指定的fd_set集合中,设置好要检查的I/O活动。调用 select函数,然后等待。select完成并返回后,会修改每个 fd_set结构,删除那些不存在待决I/O操作的套接字句柄,在各个fd_set集合中返回符合条件的套接字。,根据select的返回值,使用 FD_ISSET宏,对每个fd_set集合进行检查,判断一个特定的套接字是否仍在集合中,便可判断出哪些套接字存在着尚未完成(待决)的I/O操作。知道了每个集合中“待决”的I/O操作之后,对相应的套接字的I/O进行处理,然后返回步骤1,继续进行select处理。,4举例下面的例子用select管理一个套接字上的I/O操作:SOCKET s;/定义一个套接字fd_set fdread;/定义一个套接字集合变量int ret;/返回值/创建一个套接字,并接受连接.,/管理该套接字上的输入/输出while(TRUE)FD_ZERO(/将套接字 s 添加到fdread集合中/调用select()函数,并等待它的完成,/这里只是想检查s是否有数据可读if(ret=select(0,&fdread,NULL,NULL,NULL)=SOCKET_ERROR)/处理错误的代码,/返回值大于零,说明有符合条件的套接字/对于本例这个简单的情况,select()的返回值应是1。/如果程序处理更多的套接字,返回值可能大于1,/应用程序应检查特定的套接字是否在返回的集合中if(ret 0)if(FD_ISSET(s,&fdread)/对该套接字进行读操作,8.2 WSAAsyncSelect异步I/O模型,异步I/O模型通过调用WSAAsyncSelect函数实现。利用这个模型,应用程序可在一个套接字上,接收以Windows 消息为基础的网络事件通知。该模型最早出现于Winsock的1.1中,以适应其多任务消息环境。,1WSAAsyncSelect函数函数的定义是:int WSAAsyncSelect(SOCKET s,HWND hWnd,unsigned int wMsg,long lEvent);,2窗口回调例程 应用程序在一个套接字上调用WSAAsyncSelect函数时,该函数的hWnd参数指定了一个窗口句柄。函数成功调用后,当指定的网络事件发生时,会自动执行该窗口对应的窗口回调例程。并将网络事件通知和Windows消息的相关信息,传递给该例程的入口参数,用户可以在该例程中添加自己的代码,针对不同的网络事件进行处理,从而实现有序的套接字输入和输出。,窗口回调例程应定义成如下形式:LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);,3举例,8.3 WSAEventSelect事件选择模型,WSAEventSelect事件选择模型和 WSAAsyncSelect模型类似,它也允许程序在一个或多个套接字上,接收以事件为基础的网络事件通知。表8.2总结的由WSAAsyncSelect模型采用的网络事件,均可原封不动地移植到事件选择模型中。也就是说,在用新模型开发的应用程序中,也能接收和处理所有那些事件。该模型最主要的差别在于,网络事件会投递至一个事件对象句柄,而非投递至一个窗口例程。以下按照使用此模型的编程步骤介绍。,1创建事件对象句柄 事件选择模型要求应用程序针对每一个套接字,首先创建一个事件对象。方法是调用WSACreateEvent函数,它的定义如下:WSAEVENT WSACreateEvent(void);返回值:一个创建好的事件对象句柄。,2关联套接字和事件对象,注册关心的网络事件 有了事件对象句柄后,接下来将其与某个套接字关联在一起,同时注册感兴趣的网络事件类型(表8-2),这就需要调用WSAEventSelect函数:int WSAEventSelect(SOCKET s,WSAEVENT hEventObject,long lNetworkEvents);,3.等待网络事件触发事件对象句柄的工作状态 套接字同一个事件对象句柄关联在一起以后,程序便调用WSAWaitForMultipleEvents函数,等待网络事件触发事件对象句柄的工作状态:DWORD WSAWaitForMultipleEvents(DWORD cEvents,const WSAEVENT FAR*lphEvents,BOOL fWaitAll,DWORD dwTimeout,BOOL fAlertable);该函数用来等待一个或多个事件对象句柄,当其中一个或所有句柄进入“已传信”状态后,或在超过了一个规定的时间期限后,立即返回。,4检查套接字上所发生的网络事件类型 知道了造成网络事件的套接字后,接下来可调用WSAEnumNetworkEvents函数,检查套接字上发生了什么类型的网络事件。该函数定义如下:int WSAEnumNetworkEvents(SOCKET s,WSAEVENT hEventObject,LPWSANETWORKEVENTS lpNetworkEvents);,5处理网络事件 在确定了套接字上发生的网络事件类型后,可以根据不同的情况做出相应的处理。完成了对WSANETWORKEVENTS 结构中的事件的处理之后,应用程序应在所有可用的套接字上,继续等待更多的网络事件。完成了对一个事件对象的处理后,应调用WSACloseEvent函数,释放由事件句柄使用的系统资源。函数的定义如下:BOOL WSACloseEvent(WSAEVENT hEvent);该函数也将一个事件句柄作为自己唯一的参数,并会在成功后返回TRUE,失败后返回FALSE。,6举例,8.4 其他模型,重叠I/O 模型 在Winsock中,能使应用程序达到更佳的性能。重叠模型的基本原理是让应用程序使用一个重叠的数据结构,一次投递一个或多个Winsock 的I/O请求。针对那些提交的请求,在它们完成之后,应用程序可为它们提供服务。自Winsock 2.0发布开始,重叠I/O便已集成到新的Winsock函数中。因此,重叠I/O模型适用于安装了Winsock 2.0的所有Windows平台。,“完成端口”模型 是迄今为止最为复杂的一种I/O模型。然而,假若一个应用程序同时需要管理为数众多的套接字,那么采用这种模型,往往可以达到最佳的系统性能!该模型只适用于Windows NT和Windows 2000 操作系统。因其设计的复杂性,只有在你的应用程序需要同时管理数百乃至上千个套接字的时候,而且希望随着系统内安装的CPU数量的增多,应用程序的性能也可以线性提升时,才应考虑采用“完成端口”模型。,

    注意事项

    本文(网络编程实用教程第7-8章-多线程编程.ppt)为本站会员(牧羊曲112)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开