网络编程实用教程第7-8章-多线程编程_第1页
网络编程实用教程第7-8章-多线程编程_第2页
网络编程实用教程第7-8章-多线程编程_第3页
网络编程实用教程第7-8章-多线程编程_第4页
网络编程实用教程第7-8章-多线程编程_第5页
已阅读5页,还剩57页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

网络编程实用教程,第7章WinSock的多线程编程,本章内容:WinSock需要多线程编程的原因:Win32操作系统下的多进程多线程机制、多线程机制在网络编程中的应用和VisualC+6.0对多线程网络编程的支持。分析了MFC支持的两种线程,给出了创建MFC的工作线程、创建并启动用户界面线程和终止线程的步骤。,7.1WinSock为什么需要多线程编程,7.1.1WinSock的两种输入输出模式,如前所述,WinSock在进行输入输出的时候,可以使用两种工作模式:“阻塞”模式:又称为同步模式“非阻塞”模式:又称为异步模式工作在“阻塞”模式下的套接字被称为阻塞套接字,而工作在“非阻塞”模式下的套接字称为非阻塞套接字。,7.1.2两种模式的优缺点及解决方法,“阻塞”与“非阻塞”模式的优点和缺点:阻塞套接字的I/O操作工作情况比较确定,即调用、等待、返回。大部分情况下,I/O操作都能成功地完成,只是花费了等待的时间,容易编程;需要建立多个套接字连接来为多个客户服务的时候,或在数据的收发量不均匀的时候,或在输入输出的时间不确定的时候,阻塞套接字的性能低下,甚至无能为力。,使用非阻塞套接字,需要编写更多的代码,因为必须恰当地把握调用I/O函数的时机,尽量减少无功而返的调用,还必须详加分析每个Winsock调用中收到的错误,采取相应的对策,这种I/O操作的随机性使得非阻塞套接字显得难于操作。所以必须采取适当的对策,让阻塞和非阻塞套接字能够满足各种场合的要求。对于非阻塞工作模式:引入了五种“套接字I/O模型”。阻塞的工作模式,则引入了多线程机制。,7.2Win32操作系统下的多进程多线程机制,7.2.2Win32OS支持多线程,应用程序、进程及线程的关系DOS是单用户单任务的。Win32操作系统是多任务的,并且支持一个进程中有多个线程。一个线程(thread)是进程内的一条执行路径,是一个应用程序中的一条可执行路径。一个进程中至少要有一个线程,称为主线程。当启动了一个应用程序时,操作系统将为它创建了一个进程,同时创建该进程的主线程,并开始执行主线程。主线程可以创建并启动其他辅助线程,由主线程创建的线程又可以创建并启动更多的线程。,7.2.2Win32OS支持多线程,单CPU分时地运行进程中的各个线程,7.2.3多线程机制在网络编程中的应用,如果一个应用程序,有多个任务需要同时进行处理,则适合使用多线程机制。对于网络上客户机软件:采用多线程,能克服在单线程的编程模式下,由于阻塞等待而产生的客户程序就不能及时响应用户的操作命令的问题。对于网络上服务器软件:采用多线程的编程技术,能更好地为多个客户服务。对于一个客户:采用多线程机制也能大大提高应用程序的运行效率。网络在线实时监控软件:,7.3VC6.0对多线程网络编程的支持,VC6.0环境下,两种开发程序的方法:直接使用Win32API来编写Win32应用程序利用MFC基础类库编写C+风格的应用程序。在这两种Windows应用程序的开发方式下,多线程的编程原理是一致的。,7.3.1MFC支持的两种线程,微软的基础类库MFC提供了对于多线程应用程序的支持。在MFC中,线程分为两种:用户接口线程:(user-interfacethread),或称用户界面线程;工作线程:(theworkerthread),这两类线程可以满足不同任务的处理需求。,1、用户接口线程作用:用于处理用户的输入,响应用户产生的消息。MFC为用户接口线程提供了一个消息泵。同时包含一个消息循环,以应对各种事件。MFC应用程序的CWinApp类对象是一个典型的用户接口线程在MFC应用程序中,CWinThread是用户接口线程的基类,CWinApp就是从CWinThread类派生出来的,编写用户接口线程候,也需要从CWinThread类派生。,2工作线程工作线程(workerthread),适用于处理那些不要求用户输入并且比较消耗时间的其他任务。对用户来说,工作线程运行在后台。这就使得工作线程特别适合去等待一个事件的发生。CWinThread类同样是工作线程的基类。在编写工作线程的时候,可以调用MFC的AfxBeginThread函数,来创建CWinThread对象。,7.3.2创建MFC的工作线程,利用MFC创建工作线程的步骤:第一步:编程实现控制函数第二步:创建并启动工作线程一般不必从CWinThread派生一个类。如果需要一个特定版本的CWinThread类,也可以去派生;但对于大多数的工作线程是不要求的。可以不作任何修改地使用CWinThread类。,7.3.2创建MFC的工作线程,1、编程实现控制函数一个工作线程对应一个控制函数。线程执行的任务都应编写在控制函数之中,规定了该线程的执行代码,当控制函数执行结束而退出时,线程也就随之终止。编写工作线程的控制函数必须遵守一定的格式,控制函数的原型声明是:UINTControlFunctionName(LPVOIDpParam);pParam是一个数据结构;,7.3.2创建MFC的工作线程,2创建并启动工作线程(Startingthethread)启动线程:即开始运行它对应的控制函数。在主线程或其他线程中调用AfxBeginThread()函数就可以创建新的线程,并使新线程开始运行。一般将线程的创建者称为新线程的父线程。AfxBeginThread()函数有两个重载的版本,区别在于使用的入口参数不同。,7.3.2创建MFC的工作线程,CWinThread*AfxBeginThread(AFX_THREADPROCpfnThreadProc,/控制函数的地址LPVOIDpParam,/数据结构的指针,传数据给线程控制函数intpPriority=THREAD_PRIORITY_NORMAL,/优先级UINTnStackSize=0,/线程的堆栈大小(缓冲区)DWORDdwCreateFlags=0,/线程的运行状态,是否被挂起LPSECURITY_ATTTRIBUTESlpSecurityAttrs=NULL/安全属性);后面4个参数为可选参数。,创建工作线程的例子,3、创建工作线程的例子功能:求长度为N的数组Arry的各元素的和。编程实现线程控制函数(1)/首先定义了一个结构:structintN;/数组元素的个数。double*Arry;/指向一个双精度实数的数组myData;/定义了此结构类型的变量,省略了初始化的代码myDatass;,创建工作线程的例子,(2)/接着定义线程的控制函数。UINTMyCalcFunc(LPVOIDpParam)/如果入口参数为空指针,终止线程。if(pPara=NULL)AfxEndThread(MY_NULL_POINTER_ERROR);intN=pPara-N;/数组的元素个数。double*Arry=pPara-Arry;/指向数组的第一个元素。doublesum=0;/数组元素之和。for(inti=0;i0)if(FD_ISSET(s,2窗口回调例程应用程序在一个套接字上调用WSAAsyncSelect函数时,该函数的hWnd参数指定了一个窗口句柄。函数成功调用后,当指定的网络事件发生时,会自动执行该窗口对应的窗口回调例程。并将网络事件通知和Windows消息的相关信息,传递给该例程的入口参数,用户可以在该例程中添加自己的代码,针对不同的网络事件进行处理,从而实现有序的套接字输入和输出。,窗口回调例程应定义成如下形式:LRESULTCALLBACKWindowProc(HWNDhWnd,UINTuMsg,WPARAMwParam,LPARAMlParam);,3举例,8.3WSAEventSelect事件选择模型,WSAEventSelect事件选择模型和WSAAsyncSelect模型类似,它也允许程序在一个或多个套接字上,接收以事件为基础的网络事件通知。表8.2总结的由WSAAsyncSelect模型采用的网络事件,均可原封不动地移植到事件选择模型中。也就是说,在用新模型开发的应用程序中,也能接收和处理所有那些事件。该模型最主要的差别在于,网络事件会投递至一个事件对象句柄,而非投递至一个窗口例程。以下按照使用此模型的编程步骤介绍。,1创建事件对象句柄事件选择模型要求应用程序针对每一个套接字,首先创建一个事件对象。方法是调用WSACreateEvent函数,它的定义如下:WSAEVENTWSACreateEvent(void);返回值:一个创建好的事件对象句柄。,2关联套接字和事件对象,注册关心的网络事件有了事件对象句柄后,接下来将其与某个套接字关联在一起,同时注册感兴趣的网络事件类型(表8-2),这就需要调用WSAEventSelect函数:intWSAEventSelect(SOCKETs,WSAEVENThEventObject,longlNetworkEvents);,3.等待网络事件触发事件对象句柄的工作状态套接字同一个事件对象句柄关联在一起以后,程序便调用WSAWaitForMultipleEvents函数,等待网络事件触发事件对象句柄的工作状态:DWORDWSAWaitForMultipleEvents(DWORDcEvents,constWSAEVENTFAR*lphEvents,BOOLfWaitAll,DWORDdwTimeout,BOOLfAlertable);该函数用来等待一个或多个事件对象句柄,当其中一个或所有句柄进入“已传信”状态后,或在超过了一个规定的时间期限后,立即返回。,4检查套接字上所发生的网络事件类型知道了造成网络事件的套接字后,接下来可调用WSAEnumNetworkEvents函数,检查套接字上发生了什么类型的网络事件。该函数定义如下:intWSAEnumNetworkEvents(SOCKETs,WSAEVENThEventObject,LPWSANETWORKEVENTSlpNetworkEvents);,5处理网络事件在确定了套接字上发生的网络事件类型后,可以根据不同的情况做出相应的处理。完成了对WSANETWORKEVENTS结构中的事件的处理之后,应用程序应在所有可用的套接字上,继续等待更多的网络事件。完成了对一个事件对象的处理后,应调用WSACloseEvent函数,释放由事件句柄使用的系统资源。函数的定义如下:BOOLWSACloseEvent(WSAEVENThEvent);该函数也将一个事件句柄作为自己唯一的参数,并会在成功后返回TRUE,失败后返回FALSE。,6举例,8.4其他模型,重叠I/O模型在Winsock中,能使应用程序达到更佳的性能。重叠模型的基本原理是让应用程序使用一个重叠的数据结构,一次投递一个或多个Winsock的I/O请求。针对那些提交的请求,在它们完成之后,应用程序可为它们提供服务。自Winsock2.0发布开始,重叠I/O便已集成到新的Winsock函数中。

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论