- 1、本文档共11页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
第5章进程间通信
第5章进程间通信为了实现特殊的目的,系统编程时往往使用多个进程,这些进程往往会使用动态链接库为纽带,实现进程间的数据通信。进程间的数据通信方法有很多,如果只是一个简单的通知事件,可以采用Win32提供的系统对象比如信号灯、互斥、关键临界区、事件等。如果需要大量的数据通信,而又不在乎速度和性能,适时性要求不高可以采用文件、注册表和WindowsNT提供的事件日志等。对于适时性要求较高的场合,可以采用创建内存共享文件、创建管道、邮槽,通过窗口消息来实现消息共享。对于远程的应用程序,还可以通过socket和有关网络协议实现通信。前面已经提到了多种方法,比如内存共享文件、动态链接库的共享节等,这里主要介绍系统内核对象的应用以及其他几种进程间通信的方法。5.1 只启动一份程序实例只保留一份应用程序实例的目的是显而易见的,它主要是防止在多个实例加载的系统中造成资源浪费,同时也可以避免多个实例存取同一系统对象造成的各种冲突。为了只允许运行程序的一个实例,往往需要在程序运行时,对系统进行检查,发现已经有一个实例存在就立即退出。由于每一个进程启动时都会有一个进程标识,有时会创建自己的主窗口,在注册表或者系统文件中写入一些标记信息,有时也会创建一些系统对象,这些信息都可以作为查找前面一个实例存在的标志。前面介绍进程枚举时提到了通过进程枚举得到各个进程标识,进而得到进程名称的实现。实际上这个过程本身就可以作为查找应用程序实例的一种方法。一般地,用户会尽可能地避免修改可执行文件的名称,而进程文件名称重名的几率虽然存在,但是非常小,通过进程名称查找仍然是非常有效的。当然了这种方法极其繁琐,一方面它要处理WindowsNT4和Windows9x之间的差异;另一方面,进程的枚举也不是一件轻松的任务。所以这种方法的应用不是很多。通过窗口查找应该是一个简单易行的办法,因为大部分基于GUI实现的应用程序都会创建自己的窗口,这些窗口类名和窗口标题完全相同的几率很低,使用这种方法应该是简单有效的。Windows提供的FindWindow和FindWindowEx两个函数可以根据窗口类名和窗口标题来查找是否存在一个指定特征的窗口,以此来作为进程是否存在的标志。比如InternnetExplorer程序和Shell进程都有其独特的特征。利用这些特征来判断进程实例的存在是非常有效的,而且这种方法不需要创建任何系统内核对象。但是这种方法有一个很大的局限性,就是如果一个程序运行时没有窗口消息循环,这种方法就会失效。使用内核对象来识别程序实例是最精确的,相当于DNA鉴定,下面是一段采用互斥内核对象实现的,同样用户还可以使用事件、原子等对象。例5-1通过互斥对象实现惟一实例进程。HANDLECreateOneAppMutex(LPCTSTRlpName){HANDLE hMutex;//CreatemutexhMutex=CreateMutex(NULL,TRUE,lpName);switch(GetLastError()){ case ERROR_SUCCESS: break; //互斥对象创建成功,没有实例运行Case ERROR_ALREADY_EXISTS: hMutex=NULL;break; //互斥对象已经存在,程序的一个实例正在运行default: break; } //由于某个原因可能无法创建实例return hMutex;}这种方法实现的原理是基于所有系统内核对象不允许两个重名的对象共存。它实现的原理是,每个进程启动时首先根据系统的对象(事件、互斥、原子)检查该名称标识的对象是否存在。如果不存在,就创建该对象;否则直接退出。在程序退出时,系统会释放该系统对象。显然这种方法的准确性是无庸置疑的,但是使用这种方法有一定的风险,因为系统的对象的创建和释放是通过两个步骤实现的。如果在进程运行期间,系统异常退出,那么系统内核对象回收就无法实现。这样已经创建的对象将一致保持到系统注销或者重新启动时为止,除非用户采用其他方法关闭该内核对象。否则,可以设想进程本来已经异常终止,但是它申请创建的内核对象却没有释放,检查时这个对象仍然存在,这样很有可能进程将无法创建一个惟一的实例。5.2 使用共享内存实现进程间通信尽管进程间通信的方法有多种,但是对于单机而言,最底层共享的机制是内存共享文件。上面提到的多种方法都是基于内存共享文件实现的。使用内存共享文件可以提高共享的性能,降低系统开销。使用内存共享文件实现进程共享是基于同一文件映射对象的视图来实现的,各个进程会共享同一物理存储器的同一个页面,任何一个进程对该共享文件对象的修改都会同时影响其他进程对该对象的映射,它们会立即看到修改进程对共享内存对象的变更。使用内存共享文件实现共享数据,一般都会创建一个名称字符串标识的共享
文档评论(0)