进程间通信 (IPC ,Inter-Process Communication ),指至少两个进程 或线程 间传送数据或信号的一些技术或方法。进程是计算机系统 分配资源的最小单位。每个进程都有自己的一部分独立的系统资源,彼此是隔离的。为了能使不同的进程互相访问资源并进行协调工作,才有了进程间通信。这些进程 可以运行在同一计算机上或网络连接的不同计算机上。 进程间通信技术包括消息传递、同步、共享内存和远程过程调用 。 IPC是一种标准的Unix 通信机制。
目前有以下一些进程间通信的方式:
下列方式只适用于特定操作系统 平台或特定的编程语言:
有人认为这些也可以算是进程间通信的方式:
***********************************************************************************************
进程间通讯(IPC)
的四种不同技术:
1. 消息传递(管道,FIFO,posix和system v消息队列)
2.
同步(互斥锁,条件变量,读写锁,文件和记录锁,Posix和System V信号灯)
3.
共享内存区(匿名共享内存区,有名Posix共享内存区,有名System V共享内存区)
4. 过程调用(Solaris门,Sun RPC)
消息队列和过程调用往往单独使用,也就是说它们通常提供了自己的同步机制.相反,共享内存区通常需要由应用程序提供的某种同步形式才能正常工作.解决某个特定问题应使用哪种IPC不存在简单的判定,应该逐渐熟悉各种IPC形式提供的机制,然后根据特定应用的要求比较它们的特性.
必须考虑的四个前提:
1.
联网的还是非联网的.IPC适用于单台主机上的进程或线程间的.如果应用程序有可能分布到多台主机上,那就要考虑使用套接字代替IPC,从而简化以后向联网的应用程序转移的工作.
2. 可移植性.
3. 性能,在具体的开发环境下运行测试程序,比较几种IPC的性能差异.
4.
实时调度.如果需要这一特性,而且所用的系统也支持posix实时调度选项,那就考虑使用Posix的消息传递和同步函数.
各种IPC之间的一些主要差异:
1. 管道和FIFO是字节流,没有消息边界.Posix消息和System
V消息则有从发送者向接受者维护的记录边界(eg:TCP是没有记录边界的字节流,UDP则提供具有记录边界的消息).
2.
当有一个消息放置到一个空队列中时,Posix消息队列可向一个进程发送一个信号,或者启动一个新的线程.System V则不提供类似的通知形式.
3.
管道和FIFO的数据字节是先进先出的.Posix消息和System
V消息具有由发送者赋予的优先级.从一个Posix消息队列读出时,首先返回的总是优先级最高的消息.从一个System
V消息队列读出时,读出者可以要求想要的任意优先级的消息.
4. 在众多的消息传递技术—管道,FIFO,Posix消息队列和System
V消息队列—中,可从一个信号处理程序中调用的函数只有read和write(适用于管道和FIFO).
比较不同形式的消息传递时,我们感兴趣的有两种测量尺度:
1.
带宽(bandwidth):数据通过IPC通道转移的速度.为测量该值,我们从一个进程向另一个进程发送大量数据(几百万字节).我们还给不同大小的I/O操作(例如管道和FIFO的write和read操作)测量该值,期待发现带宽随每个I/O操作的数据量的增长而增长的规律.
2.
延迟(latency):一个小的IPC消息从一个进程到令一个进程再返回来所花的时间.我们测量的是只有一个1个字节的消息从一个进程到令一个进程再回来的时间(往返时间)
在现实世界中,带宽告诉我们大块数据通过一个IPC通道发送出去需花多长时间,然而IPC也用于传递小的控制信息,系统处理这些小消息所需的时间就由延迟提供.这两个数都很重要.
***********************************************************************************************
进程间通信的11种方法
Using named objects
Waiting for multiple objects
Waiting in a message loop
Using mutex objects
Using semaphore objects
Using event objects
Using critical section objects
Using timer queues
Using waitable timer objects
CreateFileMapping
我觉得还是用event比较方便
进程间的通讯实现(IPC)的11种方法
进程通常被定义为一个正在运行的程序的实例,它由两个部分组成:
一个是操作系统用来管理进程的内核对象。内核对象也是系统用来存放关于进程的统计信息的地方
另一个是地址空间,它包含所有的可执行模块或DLL模块的代码和数据。它还包含动态分配的空间。如线程堆栈和堆分配空间。每个进程被赋予它自己的虚拟地址空间,当进程中的一个线程正在运行时,该线程可以访问只属于它的进程的内存。属于其它进程的内存则是隐藏的,并不能被正在运行的线程访问。
为了能在两个进程之间进行通讯,由以下几种方法可供参考:
0。剪贴板Clipboard: 在16位时代常使用的方式,CWnd中提供支持
1。窗口消息 标准的Windows消息以及专用的WM_COPYDATA消息 SENDMESSAGE()接收端必须有一个窗口
2。使用共享内存方式(Shared Memory)
a.设定一块共享内存区域
HANDLE CreateFileMapping(HANDLE,LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR)
产生一个file-mapping核心对象
LPVOID MapViewOfFile(
HANDLE hFileMappingObject,
DWORD dwDesiredAcess,
DWORD dwFileOffsetHigh,
DWORD dwFileOffsetLow,
DWORD dwNumberOfBytesToMap
);
得到共享内存的指针
b.找出共享内存
决定这块内存要以点对点(peer to peer)的形式呈现
每个进程都必须有相同的能力,产生共享内存并将它初始化。每个进程
都应该调用CreateFileMapping(),然后调用GetLastError().如果传回的
错误代码是ERROR_ALREADY_EXISTS,那么进程就可以假设这一共享内存区 域已经被别的进程打开并初始化了,否则该进程就可以合理的认为自己 排在第 一位,并接下来将共享内存初始化。
还是要使用client/server架构中
只有server进程才应该产生并初始化共享内存。所有的进程都应该使用
HANDLE OpenFileMapping(DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCTSTR lpName);
再调用MapViewOfFile(),取得共享内存的指针
c.同步处理(Mutex)
d.清理(Cleaning up) BOOL UnmapViewOfFile(LPCVOID lpBaseAddress);
CloseHandle()
3。动态数据交换(DDE)通过维护全局分配内存使的应用程序间传递成为可能
其方式是再一块全局内存中手工放置大量的数据,然后使用窗口消息传递内存 指针.这是16位WIN时代使用的方式,因为在WIN32下已经没有全局和局部内存 了,现在的内存只有一种就是虚存。
4。消息管道(Message Pipe)
用于设置应用程序间的一条永久通讯通道,通过该通道可以象自己的应用程序
访问一个平面文件一样读写数据。
匿名管道(Anonymous Pipes)
单向流动,并且只能够在同一电脑上的各个进程之间流动。
命名管道(Named Pipes)
双向,跨网络,任何进程都可以轻易的抓住,放进管道的数据有固定的格 式,而使用ReadFile()只能读取该大小的倍数。
可以被使用于I/O Completion Ports
5 邮件槽(Mailslots)
广播式通信,在32系统中提供的新方法,可以在不同主机间交换数据,在 WIN9X下只支持邮件槽客户
6。Windows套接字(Windows Socket)
它具备消息管道所有的功能,但遵守一套通信标准使的不同操作系统之上的应 用程序之间可以互相通信。
7。Internet通信 它让应用程序从Internet地址上载或下载文件
8。RPC:远程过程调用,很少使用,因其与UNIX的RPC不兼容。
9。串行/并行通信(Serial/Parallel Communication)
它允许应用程序通过串行或并行端口与其他的应用程序通信
10。COM/DCOM
通过COM系统的代理存根方式进行进程间数据交换,但只能够表现在对接口 函数的调用时传送数据,通过DCOM可以在不同主机间传送数据
***********************************************************************************************