扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
进程间的数据交换和共享是一种非常重要和实用的技术。大、中型软件的开发设计多是由众多程序设计人员的合作完成,通常一个程序设计人员只负责其中一个或几个模块的开发,这些模块可以是动态链接库也可以是应用程序或是其他形式的程序组件。这些独立开发出来的程序模块最终需要作为一个整体来运行,即组成一个系统,在系统运行期间这些模块往往需要频繁地进行数据交换和数据共享,对于动态链接库同其主调应用程序之间的数据交换是非常容易实现的,但是在两个应用程序之间或是动态链接库同其主调应用程序之外的其他应用程序进行数据交换就比较困难了。尤其是在交换数据量过大、交换过于频繁的情况下更是难以实现,本文即对此展开讨论,并提出了一种通过共享内存来实现进程见大数据量快速交换的一种方法。
通讯方式的比较和选择
进程间通讯的方式有很多,常用的有共享内存、命名管道和匿名管道、发送消息等几种方法来直接完成,另外还可以通过socket口、配置文件和注册表等来间接实现进程间数据通讯任务。以上这几种方法各有优缺点,具体到在进程间进行大数据量数据的快速交换问题上,则可以排除使用配置文件和注册表的方法;另外,由于管道和socket套接字的使用需要有网卡的支持,因此也可以不予考虑。这样,可供选择的通讯方式只剩下共享内存和发送消息两种。由于数据量比较大,这样在使用消息进行通讯时就无法通过消息参数将数据直接携带到接收方,只能以地址传送的方式进行。当一个应用程序向另一个应用程序发送数据时将会发出WM_COPYDATA系统消息,因此可以考虑通过向消息队列插入WM_COPYDATA消息的方法来实现数据在进程间的拷贝。
在使用WM_COPYDATA消息时,由第一个消息参数指定发送窗口的句柄,第二个消息参数则为一同数据相关的数据结构COPYDATASTRUCT的指针,此结构原形声明如下:
typedef struct tagCOPYDATASTRUCT { DWORD dwData; DWORD cbData; PVOID lpData; } COPYDATASTRUCT; |
其中,只需将待发送数据的首地址赋予lpData、并由cbData指明数据块长度即可。消息发出后,接收方程序在WM_COPYDATA消息的响应函数中通过随消息传递进来的第二个参数完成对数据块的接收。但是在使用WM_COPYDATA消息时,只能用SendMessage()函数发送而不能使用PostMessage(),这两个函数虽然功能非常相似都是负责向指定的窗口发送消息,但是SendMessage()函数发出消息后不是马上返回,而是在接收方的消息响应函数处理完之后才能返回,并能够得到返回结果。在此期间发送方程序将被阻塞,SendMessage()后面的语句不能被继续执行。而PostMessage()函数在发出消息后马上返回,其后语句能够被立即执行,但是无法获取消息的执行结果。可见,在交换数据量较大的情况下实现数据频繁而又快速的交换用发送WM_COPYDATA消息的方法也是不合适的,当数据传输过于频繁时将有可能导致数据的丢失。
比之以上几种进程间通讯方法,共享内存有着明显的优势。共享内存是通过直接操作内存映射文件来进行的,而内存映射文件又是进行单机数据共享的最低层机制,前面几种数据交换方式在低层都是通过内存映射文件来进行的。因此使用共享内存可以以较小的开销获取较高的性能,是进行大数据量数据快速交换的最佳方案。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者