




已阅读5页,还剩29页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
实验7WinSock多线程编程 7 1WinSock为什么需要多线程编程7 1 1WinSock的两种输入输出模式如前所述 WinSock在进行输入输出的时候 可以使用两种工作模式 即 阻塞 模式 BlockingMode 或 非阻塞 模式 又称为同步模式或异步模式 工作在 阻塞 模式的套接字称为阻塞套接字 工作在 非阻塞 模式下的套接字称为非阻塞套接字 阻塞模式在I O操作完成前不会立即交出CPU控制权返回 独占的运行方式使整个进程处于阻塞的等待状态 采用阻塞进程的单进程服务器不能很好的同时为多个客户机服务 非阻塞模式时 进程调用并执行I O时 无论操作是否完成 函数会立即返回 7 1 2两种模式的优缺点及解决方法 阻塞 与 非阻塞 模式各有其优点和缺点 阻塞套接字的I O操作工作情况比较确定 无非是调用 等待 返回 大部分情况下 I O操作都能成功地完成 不过就是花费了等待的时间 因而比较容易使用 容易编程 但在应付诸如需要建立多个套接字连接来为多个客户服务的时候 或在数据的收发量不均匀的时候 或在输入输出的时间不确定的时候 却显得性能低下 甚至无能为力 使用非阻塞套接字 需要编写更多的代码 因为必须恰当地把握调用I O函数的时机 尽量减少无功而返的调用 还必须详加分析每个Winsock调用中收到的WSAEWOULDBLOCK错误 采取相应的对策 这种I O操作的随机性使得非阻塞套接字显得难于操作 所以 必须采取一些适当的对策 克服这两种模式的缺点 让阻塞和非阻塞套接字能够满足各种场合的要求 对于非阻塞的套接字工作模式 进一步引入了五种 套接字I O模型 对于阻塞的套接字工作模式 则进一步引入了多线程机制 7 2Win32操作系统下的多进程多线程机制7 2 1Win32OS是单用户多任务的操作系统最早的DOS是单用户单任务的 后来发展到图形界面的Windows 发展到Windows95 Windows98 就都支持多任务了 从WindowsNT起 Windows操作系统更是发展成了一个真正的抢占式多任务操作系统 7 2 2Win32OS是支持多线程的操作系统Win32操作系统还支持同一进程的多线程 在一个Windows进程内 可以包含多个线程 一个线程 thread 是进程内的一条执行路径 具体地说 是一个应用程序中的一条可执行路径 往往是应用程序中的一个或多个函数 一个进程中至少要有一个线程 习惯将它称为主线程 任何一个应用程序进程都有一个主线程 一般C程序中的Main或WinMain函数就规定了主线程的执行代码 当你启动了一个应用程序时 操作系统在为它创建了进程之后 也创建了该进程的主线程 并根据Main或WinMain函数的地址 开始执行该进程的主线程 主线程可以创建并启动其他辅助线程 由主线程创建的线程又可以创建并启动更多的线程 一个线程也需要占用一定的系统资源 线程是进程中相对独立的执行单位 也是Win32操作系统中可调度的最小的执行单位 多个进程中的多个线程并发地执行 对于拥有多个处理机的计算机系统 调度程序可以将不同的线程安排到不同的处理机上去运行 一方面平衡了CPU的负载 另一方面也提高了系统的运行效率 当某个线程的代码都执行完毕时 该线程会自动终止 当一个线程终止时 会将它所占用的资源释放给进程 7 2 3多线程机制在网络编程中的应用如果一个应用程序 有多个任务需要同时进行处理 那就最适合使用多线程机制 对于网络上客户机软件 采用多线程的编程技术 能克服在单线程的编程模式下 由于阻塞等待而产生的客户程序就不能及时响应用户的操作命令的问题 对于网络上服务器软件 采用多线程的编程技术 能更好地为多个客户服务 即便是对于一个客户 采用多线程机制也能大大提高应用程序的运行效率 比如大家熟悉的东方快车 网络蚂蚁等文件下载软件 就采用了多线程机制 用多个线程同时下载一个文件的不同部分 大大加快了下载速度 7 3VisualC 6 0对多线程网络编程的支持VisualC 6 0为程序员提供了Windows应用程序的集成开发环境 在这个环境下 有两种开发程序的方法 既可以直接使用Win32API来编写C风格的Win32应用程序 也可以利用MFC基础类库编写C 风格的应用程序 在这两种Windows应用程序的开发方式下 多线程的编程原理是一致的 7 3 1MFC支持的两种线程微软的基础类库MFC提供了对于多线程应用程序的支持 在MFC中 线程分为两种 一种是用户接口线程 user interfacethread 或称用户界面线程 另一种是工作线程 theworkerthread 这两类线程可以满足不同任务的处理需求 1 用户接口线程用户接口线程通常用来处理用户输入产生的消息和事件 并独立地响应正在应用程序其它部分执行的线程们产生的消息和事件 MFC特别地为用户接口线程提供了一个消息泵 amessagepump 用户接口线程包含一个消息处理的循环 以应对各种事件 在MFC应用程序中 所有的线程都是由CWinThread对象来表示的 CWinThread类 可以理解为C 的Windows线程类 是用户接口线程的基类 CWinApp就是从CWinThread类派生出来的 我们在编写用户接口线程的时候 也需要从CWinThread类派生出自己的线程类 借助ClassWizard可以很容易地做这项工作 2 工作线程工作线程适用于处理那些不要求用户输入并且比较消耗时间的其他任务 对用户来说 工作线程运行在后台 这就使得工作线程特别适合去等待一个事件的发生 CWinThread类同样是工作线程的基类 同样是由对象来表示的 但在编写工作线程的时候 你甚至不必刻意地从CWinThread类派生出自己的线程类对象 你可以调用MFC框架的AfxBeginThread帮助函数 它会为你创建CWinThread对象 Win32API不区分两种线程 只需知道线程起始地址就可开始执行线程 7 3 2创建MFC的工作线程下面介绍利用MFC创建工作线程所必需的步骤 创建一个工作线程是一个相对简单的任务 只要经过两个步骤就能使你的工作线程运行 第一步是编程实现控制函数 第二步是创建并启动工作线程 一般不必从CWinThread派生一个类 当然 如果你需要一个特定版本的CWinThread类 也可以去派生 但对于大多数的工作线程是不要求的 可以不作任何修改地使用CWinThread类 1 编程实现控制函数 implementingthecontrollingfunction 一个工作线程对应一个控制函数 thecontrollingfunction 线程执行的任务都应编写在控制函数之中 控制函数规定了该线程的执行代码 所谓启动线程 实际就是开始运行它对应的控制函数 当控制函数执行结束而退出时 线程也就随之终止 编写实现工作线程的控制函数是创建工作线程的第一步 编写工作线程的控制函数必须遵守一定的格式 控制函数的原型声明是 UINTControlFunctionName LPVOIDpParam 2 创建并启动工作线程 Startingthethread 在进程的主线程或其他线程中调用AfxBeginThread 函数就可以创建新的线程 并使新线程开始运行 一般将线程的创建者称为新线程的父线程 AfxBeginThread 函数是MFC提供的帮助函数 有两个重载的版本 区别在于使用的入口参数不同 一个用于创建并启动用户接口线程 一个用于创建并启动工作线程 要创建并启动你的工作线程 必须采用如下的调用格式 CWinThread AfxBeginThread AFX THREADPROCpfnThreadProc LPVOIDpParam intpPriority THREAD PRIORITY NORMAL UINTnStackSize 0 DWORDdwCreateFlags 0 LPSECURITY ATTTRIBUTESlpSecurityAttrs NULL 3 创建工作线程的例子 1 编程实现线程控制函数 首先定义了一个结构 struct intnN 数组元素的个数 double pD 指向一个双精度实数的数组 myData 然后定义了此结构类型的变量 对该变量初始化 对其成员变量赋值 的代码省略了 myDatass 接着定义线程的控制函数 UINTMyCalcFunc LPVOIDpParam 如果入口参数为空指针 终止线程 if pPara NULL AfxEndThread MY NULL POINTER ERROR intnN pPara nN 数组的元素个数 double pD pPara pD 指向数组的第一个元素 doublesum 0 数组元素之和 for inti 0 i nN i sum pD i 求和 CStringbb bb Format 数组的和是 d sum 格式化显示字符串 AfxMessageBox bb 显示结果 return0 2 在程序进程的主线程中调用AfxBeginThread 函数来创建并启动运行这个线程 将控制函数名和结构变量的地址作为参数来传递 其他的参数省略 表示使用默认值 AfxBeginThread MyCalcFunc 一旦调用了此函数 线程就被创建 并开始执行线程函数 当数据的计算完成时 函数将停止运行 相应的线程也随即终止 线程拥有的堆栈和其他资源都将释放 CWinThread对象将被删除 4 创建工作线程的一般模式从上面的例子中可以得出创建工作线程的一般模式 1 工作线程控制函数的框架 UINTMyThreadProc LPVOIDpParam CMyObject pObject CMyObject pParam 进行参数的传递 如果入口参数无效就返回 if pObject NULL pObject IsKindOf RUNTIME CLASS CMyObject return1 利用入口参数作某些事情 这是工作线程要完成的主要工作 return0 线程成功地完成并返回 2 在程序的另一个函数中插入以下代码 pNewObject newCMyObject AfxBeginThread MyThreadProc pNewObject 7 3 3创建并启动用户界面线程创建并启动用户界面线程一般要经过三个步骤 第一步是从CWinThread类派生出自己的线程类 第二步是改造这个线程类 使它能够完成用户所希望的工作 第三步是创建并启动用户界面线程 1 从CWinThread类派生出自己的线程类要创建一个MFC的用户界面线程 所要做的第一件事就是从CWinThread类派生出自己的线程类 一般借助ClassWizard来做这项工作 2 改造自己的线程类对这个派生的线程类作以下改造工作 1 在这个线程类的 h头文件中 使用DECLARE DYNCREATE宏来声明这个类 在用户线程类的 CPP实现文件中 使用IMPLEMENT DYNCREATE宏来实现这个类 前者的调用格式是 DECLARE DYNCREATE class name 其中class name是实际的类名 对一个从CObject类继承的类使用这个宏 会使得应用程序框架 framework 在运行时动态地生成该类的新对象 新线程是由主线程或其他线程在执行过程中创建的 都应支持动态创建 因为应用程序框架需要动态地创建它们 DECLARE DYNCREATE宏应放在此类的 H文件中 并应在所有需要访问此类的对象的 CPP文件中加入包含这个文件的 include语句 2 如果在类的声明中使用了DECLARE DYNCREATE宏 那就必须在类的实现文件中 使用IMPLEMENT DYNCREATE宏 它的调用格式是 IMPLEMENT DYNCREATE class name base class name 参数是实际的线程类名和它的基类名 3 这个线程类必须重载它的基类 CWinThread类 的某些成员函数 如该类的InitInstance 成员函数 对于基类的其他成员函数 可以有选择地重载 也可以使用由CWinThread类提供的缺省函数 表7 1给出了相关的成员函数 4 创建新的用户界面窗口类 如窗口 对话框 并添加所需要的用户界面控件 然后建立新建的线程类与这些用户界面窗口类的联系 5 利用类向导 为新建的线程类添加控件成员变量 添加响应消息的成员函数 为它们编写实现的代码 经过以上步骤的改造 用户的线程类已经具备了完成用户任务的能力 3 创建并启动用户界面线程要创建并启动用户界面线程 可以使用MFC提供的AfxBeginThread 函数的另一个版本 使用的调用格式是 CWinThread AfxBeginThread CRuntimeClass pThreadClass intpPriority THREAD PRIORITY NORMAL UINTnStackSize 0 DWORDdwCreateFlags 0 LPSECURITY ATTTRIBUTESlpSecurityAttrs NULL 4 AfxBeginThread 函数所作的工作当进程的主线程或其他线程调用AfxBeginThread 函数来创建一个新的用户界面线程的时候 该函数做了许多工作 1 它创建一个新的用户自己的线程类的对象 由于用户的线程类是从CWinThread类派生出来的 这个对象当然也继承了CWinThread类的属性 2 然后 MFC就自动调用新线程类中的InitInstance 函数 来初始化这个新的线程类对象实例 这是一个必须在用户派生的线程类中重载的函数 用户可在该函数中初始化线程 并分配任何需要的动态内存 如果初始化成功 函数应返回TRUE 线程就可以继续运行 如果初始化失败 比如内存申请失败 就返回FALSE 线程将停止执行 并释放所拥有的资源 3 再调用CWinThread CreateThread成员函数来开始执行这个线程 最终运行CWinThread RUN函数 进入消息循环 4 函数返回一个指向新生成的CWinThread对象的指针 可以把它保存在一个变
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 梵高自画像课件
- 培训财务发票知识课件
- 党群考试面试题目及答案
- 2025年度高端住宅小区电梯安全维护及物业管理综合服务合同
- 2025版旅游攻略深度修订及定制化电子书出版服务合同
- 2025年环保材料展台制作及绿色运输服务专项合同
- 2025年绿色环保示范工厂污水处理与达标排放服务协议
- 2025年全渠道电子商务平台技术支持与服务合同
- 2025年跨境电商信用证融资服务合作协议
- 2025年公立学校锅炉工社会保障及福利待遇执行协议
- TCAPC 016-2024 院外呼吸慢病健康管理规范
- 露天矿山安全知识培训课件
- 《中小企业员工激励机制存在的问题及完善对策研究》4000字
- 第1章 汽车4S店概述
- 呼兰河传完整版课件
- 医疗器械监管实务
- 旅游景区反恐防爆应急预案
- 实验室隐患排查培训
- 浪潮iqt在线测评题及答案
- 中外运社招在线测评题
- GB/T 18802.331-2024低压电涌保护器元件第331部分:金属氧化物压敏电阻(MOV)的性能要求和试验方法
评论
0/150
提交评论