多线程与聊天程序的创建.pdf

上传人:H****o 文档编号:56633393 上传时间:2022-11-02 格式:PDF 页数:8 大小:189.65KB
返回 下载 相关 举报
多线程与聊天程序的创建.pdf_第1页
第1页 / 共8页
多线程与聊天程序的创建.pdf_第2页
第2页 / 共8页
点击查看更多>>
资源描述

《多线程与聊天程序的创建.pdf》由会员分享,可在线阅读,更多相关《多线程与聊天程序的创建.pdf(8页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、多线程与聊天程序的创建主要内容介绍多线程以及利用多线程创建聊天室程序。程序、进程和线程程序是计算机指令的集合,它以文件的形式存储在磁盘上。进程:通常被定义为一个正在运行的程序的实例,是一个程序在其自身的地址空间中的一次执行活动。通常我们编写的程序经过编译后得到.exe文件,就是以文件的形式存在在磁盘上的,当双击.exe文件运行程序,实际就是启动了该程序的一个实例,也就是进程。一个程序可以对应多个进程,如我们可以同时打开多个记事本程序。一个进程也可以访问多个程序。进程是资源申请、调度和独立运行的单位,因此,它使用系统中的运行资源;而程序不能申请系统资源,不能被系统调度,也不能作为独立运行的单位,

2、因此,它不占用系统的运行资源。进程由两个部分组成:1、操作系统用来管理进程的内核对象。内核对象也是系统用来存放关于进程的统计信息的地方。2、地址空间。它包含所有可执行模块或DLL模块的代码和数据。它还包含动态内存分配的空间。如线程堆栈和堆分配空间。内核对象的概念:内核对象就是操作系统内部分配的一个内存块,该内存块是一个数据结构,它的成员负责维护该对象的各种信息,由于类和对象的数据结构只能被内核访问,因此应用程序无法在内存找到这些数据结构并直接改变它们的内容,我们只能通过windows 提供的一些函数对类和对象进行操作。程序、进程和线程进程进程是不活泼的。进程从来不执行任何东西,它只是线程的容器

3、。若要使进程完成某项操作,它必须拥有一个在它的环境中运行的线程,此线程负责执行包含在进程的地址空间中的代码。单个进程可能包含若干个线程,这些线程都“同时”执行进程地址空间中的代码。每个进程至少拥有一个线程,来执行进程的地址空间中的代码。当创建一个进程时,操作系统会自动创建这个进程的第一个线程,称为主线程。(也就是执行main 或 winmain 函数的线程,可以把 main 或 winmain 函数看做是主线程的进入点函数)此后,该线程可以创建其他的线程。程序、进程和线程进程地址空间系统赋予每个进程独立的虚拟地址空间。对于32 位进程来说,这个地址空间是4GB。每个进程有它自己的私有地址空间。

4、进程A 可能有一个存放在它的地址空间中的数据结构,地址是0 x12345678,而进程 B 则有一个完全不同的数据结构存放在它的地址空间中,地址是0 x12345678。当进程A 中运行的线程访问地址为0 x12345678 的内存时,这些线程访问的是进程A 的数据结构。当进程B 中运行的线程访问地址为0 x12345678 的内存时,这些线程访问的是进程B 的数据结构。进程A 中运行的线程不能访问进程B 的地址空间中的数据结构,反之亦然。4GB 是虚拟的地址空间,只是内存地址的一个范围。在你能成功地访问数据而不会出现非法访问之前,必须赋予物理存储器,或者将物理存储器映射到各个部分的地址空间。

5、物理存储器,包括了物理内存和页文件的大小,任务管理器中的“提交更改”后面是实际内存+虚拟页内存的大小,要想看页内存大小,可以打开系统安装盘下,工具-文件夹选项-查看-去掉隐藏受保护的操作系统文件的选项,多了个文件pagefile.sys,这就是页文件,这个文件给应用程序增加了可以使用的内存,通过在磁盘上划分一块控件当作内存使用增加了可以使用-内存数量,这就叫做虚拟内存,如果想修改页文件大小,选择“我的电脑,”-属性-高级 性能选项4GB 虚拟地址空间中,2GB 是内核方式分区,供内核代码、设备驱动程序、设备I/O 高速缓冲、非页面内存池的分配和进程页面表等使用,而用户方式分区使用的地址空间约为

6、2GB,这个分区是进程的私有地址空间所在的地方。一个进程不能读取、写入、或者以任何方式访问驻留在该分区中的另一个进程的数据。对于所有应用程序来说,该分区是维护进程的大部分数据的地方。程序、进程和线程线程线程由两个部分组成:1、线程的内核对象,操作系统用它来对线程实施管理。内核对象也是系统用来存放线程统计信息的地方。2、线程堆栈,它用于维护线程在执行代码时需要的所有参数和局部变量。当创建线程时,系统创建一个线程内核对象。该线程内核对象不是线程本身,而是操作系统用来管理线程的较小的数据结构。可以将线程内核对象视为由关于线程的统计信息组成的一个小型数据结构。线程总是在某个进程环境中创建。系统从进程的

7、地址空间中分配内存,供线程的堆栈使用。新线程运行的进程环境与创建线程的环境相同。因此,新线程可以访问进程的内核对象的所有句柄、进程中的所有内存和在这个相同的进程中的所有其他线程的堆栈。这使得单个进程中的多个线程确实能够非常容易地互相通信。线程只有一个内核对象和一个堆栈,保留的记录很少,因此所需要的内存也很少。因为线程需要的开销比进程少,因此在编程中经常采用多线程来解决编程问题,而尽量避免创建新的进程。程序、进程和线程线程运行操作系统为每一个运行线程安排一定的CPU 时间时间片。系统通过一种循环的方式为线程提供时间片,线程在自己的时间内运行,因时间片相当短,因此,给用户的感觉,就好像线程是同时运

8、行的一样。如果计算机拥有多个CPU,线程就能真正意义上同时运行了。单线程程序与多线程程序文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3

9、S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D

10、3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5

11、D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J

12、5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10

13、J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R1

14、0J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R

15、10J5D3S7单线程程序与多线程程序单线程程序多线程程序一个线程两个线程http:/www.sunxin.org单线程程序在一个进程地址空间中只有一个线程在运行,就好像一个人到医院,医院安排一个医生给他做手术,医生就是一个主线程。多线程程序,在一个进程地址空间中有两个线程在运行,其中有一个是主线程,如一个医生做手术,配给几个护士,医生是主线程,护士是创建的线程,由这多个线程共同完成手术,效益很高。在单 CPU 的情况,某个时刻只能有一个线程在运行,为什么还要创建多个线程?注意:每个线程都能独立完成某个功能,当移植到多个CPU 的环境中,就能真正完成并发执行。那能不能由多进程来代替多线程?是可

16、以的,但是还是多采取多线程,原因:1,进程的创建,系统要为进程分配虚拟的4GB 地址空间,占用资源比较多,而多线程共享一个进程的地址,所以占用的资源比较少,2 当进程间发生切换要交换整个地址空间,而线程交换只是执行环境的改变,效率比较高。下面编写一个多线程程序。新建一个WIN32 console 应用程序MutiThread,添加文件。#include#include DWORD WINAPI Fun1Proc(LPVOID lpParameter/thread data);void main()HANDLE hThread1;hThread1=CreateThread(NULL,0,Fun1

17、Proc,NULL,0,NULL);CloseHandle(hThread1);coutmain thread is runningendl;Sleep(10);DWORD WINAPI Fun1Proc(LPVOID lpParameter/thread data)coutthread1 is runningendl;return 0;文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文

18、档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7

19、文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S

20、7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3

21、S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D

22、3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5

23、D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J

24、5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7 然后在主函数和线程中插入一个循环不断输出,看一下这两个线程执行的交替情况,在主函数前定义全局变量int index=0;while(index+1000)coutmain thread is runningendl;while(index+1000)coutthread1 is runningendl;调试运行,发现是交替执行的

25、。下面我们写一个火车票购票的程序。购票系统允许多个同时购票,所以肯定是多线程的。再写一个线程。由新创建的线程负责火车票的销售。HANDLE hThread2;hThread2=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);CloseHandle(hThread2);Sleep(4000);DWORD WINAPI Fun2Proc(LPVOID lpParameter/thread data);DWORD WINAPI Fun1Proc(LPVOID lpParameter/thread data)/*while(index+1000)coutthread

26、1 is running0)coutthread1 sell ticket:tickets-0)coutthread2 sell ticket:tickets-endl;else break;return 0;调试运行正常。但这个程序还存在弊端:线程1 进入循环前,tickets 的值为 1,刚进入If 语句,时间片到了,线程2 就开始执行,卖出了一张票tickets变为 0,那么线程2 执行完,线程1 接着开始执行,就卖出了0 一张票,这是不允许的。如果在火车票销售有可能会出现一个座位有2 张票的情况,因为火车票售票系统是长时间运行的系统,线程不断切换,这种情况是有可能出现的。系统修改是程序

27、员来做的,那么首先要重现错误,运行系统,但是这种错误不是随时随地出现,运行了几天,有可能出现的时候程序员吃饭去了。这种错误很男重现,所以在开发系统的时候尽量避免这种文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编

28、码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档

29、编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文

30、档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7

31、文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S

32、7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3

33、S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D

34、3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7错误。原因tickets 是全局变量,两个线程访问同一个变量。就有可能产生上面的错误。可以规定上线程的同步,也就是说当一个线程在销售票的时间段内,其他的线程不能够对同一种资源tickets 进行访问,必须等到线程在销售票结束后,才允许其他的线程访问资源。为了让错误出现,我们可以在上面的程序中,if 语句前加上Sleep(1);要做到线程的同步,就要创建互斥对象,利用函数CreateMutex 来完成,查MSDN.互斥对象互斥对象(mutex)属于内核对象,它能够确保线程拥有对单个资源的互斥访问权。互斥对

35、象包含一个使用数量,一个线程ID 和一个计数器。ID 用于标识系统中的哪个线程当前拥有互斥对象,计数器用于指明该线程拥有互斥对象的次数。首先在主函数建一个匿名的互斥对象全局变量HANDLE hMutex;hMutex=CreateMutex(NULL,TRUE,NULL);然后在线程中要请求互斥对,WaitForSingleObject,查 MSDN,在两个线程中的if 语句前加上 WaitForSingleObject(hMutex,INFINITE);在一章票销售完成后要释放互斥对象ReleaseMutex(hMutex);互斥对象可以理解为一把钥匙,要进入房间,用到钥匙,直到出来,把钥匙

36、给别人,其他人才能进去。如果把请求互斥对象和释放互斥对象的代码放到循环外边,调试运行发现只有线程1 买票,分析原因。如果在主函数将hMutex=CreateMutex(NULL,TRUE,NULL);的第 2 个参数设为TRUE,调试运行,发现没有买票,原因:如果设为真,主函数拥有互斥对象的所有权,两个线程永远无法获得。即使在线程的子函数中循环体内先释放线程也不行,原因是每个互斥对象都与一个ID 号关联,在主函数中已将ID 设为主线程的id,在线程1 中释放互斥对象时,操作系统要先判断申请释放的线程1 的 id 和内部维护的id 是不是相等,如果不等,释放不成功,放回0.所以要想请求所有权就不

37、成功。所以要注意,释放互斥对象所有权时,是谁拥有谁释放。应该将 ReleaseMutex(hMutex);放到主线程中,就没问题了。如果在主线程中,加入WaitForSingleObject(hMutex,INFINITE);调试又出现上面的问题。原因每个互斥对象包含一个使用数量,一个线程ID 和一个计数器。新建一个互斥对象时,计数器为1,申请互斥时陈国,计数器又加1,释放一次计数器减1,但是目前还是1,所以线程1 和线程 2 申请互斥对象时,没有空置的互斥对象,永远也申请不到。出现异常。解决的方法是在主线程中两次释放互斥对象。hMutex=CreateMutex(NULL,TRUE,NULL

38、);WaitForSingleObject(hMutex,INFINITE);ReleaseMutex(hMutex);ReleaseMutex(hMutex);现在把线程1 和线程 2 中的代码注释掉,改为WaitForSingleObject(hMutex,INFINITE);coutthread1 is runningendl;和 WaitForSingleObject(hMutex,INFINITE);coutthread2 is runningendl;调试运行正常,分析原因。如果没有释放互斥对象,在程序结束时,操作系统会将对象空置,计数器为0,id 也为0.下面应用多线程实现一个网

39、络聊天室的功能。首先新建一个基于对话框的应用程序Chat,将对话框中的控件都删除掉。放置一个组框,标题改为:接受数据,在里面放置一个编辑框,id 改为 IDC_EDIT_RECEIVE,.在下面接着放一个组框,标题为:发送数据,组框里放置一个IP 控件和一个编辑框,编辑框的ID 为 IDC_EDIT_SEND。最后在下方放一个按钮,标题为:发送,ID 为:IDC_BTN_SEND.既然要进行网络编程,那么就要用到套接字,所以要加载套接字库,进行版本协商。MFC 提供的函数AfxSocketInit BOOLAfxSocketInit(WSADATA*lpwsaData=NULL);lpwsaD

40、ata文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5

41、D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J

42、5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10

43、J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R1

44、0J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R

45、10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10

46、R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7A pointer to a WSADATA structure.

47、If lpwsaData is not equal to NULL,then the address of the WSADATAstructure is filled by the call to:WSAStartup.This function also ensures that:WSACleanup is called for you before the application terminates.RemarksCall this function in your CWinApp:InitInstance override to initialize Windows Sockets.

48、打开CWinApp:InitInstance,添加代码if(!AfxSocketInit()AfxMessageBox(加载套接字库失败!);return FALSE;要注意,在加载套接字库时要包含一个文件#include 到 stdafx.h 中。这是一个预编译头文件,在这个头文件中,MFC 程序运行的一些必要文件,这个很关键。在 ChatDlg 类中添加一个成员函数InitSocket(),进行套接字的初始化工作,右键单击类名,添加成员函数的方法来添加,同时还要再添加一个成员变量,作为套接字描述,右键单击类名的方法来添加BOOL CChatDlg:InitSocket()m_socket=

49、socket(AF_INET,SOCK_DGRAM,0);、创建套接字if(INV ALID_SOCKET=m_socket)/判断创建成功否 MessageBox(套接字创建失败!);return FALSE;因为我们的聊天室程序中,发送端也是接收端,所以要将接收端绑定在某个ip 地址的端口上,,SOCKADDR_IN addrSock;addrSock.sin_family=AF_INET;addrSock.sin_port=htons(6000);addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);int retval;retval=bind(

50、m_socket,(SOCKADDR*)&addrSock,sizeof(SOCKADDR);/绑定if(SOCKET_ERROR=retval)closesocket(m_socket);MessageBox(绑定失败!);文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3Z5 HW6R9F7E8D7 ZV10R10J5D3S7文档编码:CC1I5I10N3

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 高考资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁