进程间通信的定义
进程是转入内存并准备执行的程序,每个程序都有私有的虚拟地址空间,由代码,数据以及它可用的系统资源(如文件,管道)组成。
由于不同的进程运行在各自的内存空间中,其中一个进程对于变量的修改对于另一方是无法感知的。因此,进程之间消息传递不能通过变量或其他数据结果直接进行,只能通过进程间通信来完成。进程间通信指不同进程间进行数据共享和交换。
进程通信的分类:
根据进程通信时信息量大小的不同,可以将进程通信划分为两大类型:
…..控制信息的通信(低级通信)—主要用于进程之间的同步,互斥,终止和挂起等控制信息的传递。
…..大批量数据信息的通信(高级通信)—主要用于进程间数据块数据的交换和共享,常见的高级通信有管道,消息队列,共享内存等。
进程通信的方式
- 文件和记录锁定
为避免两个进程同时要求访问同一资源而引起访问和操作的混乱,在进程对共享资源进行访问之前必须对其锁定,该进程访问完后再释放,这是unix为共享资源提供的互斥性保障。 - 管道
管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系一般指父子关系,管道一般用于两个进程之间的通信,当一个进程创建一个管道,并调用fork创建自己的一个子进程后,父进程关闭读端,子进程关闭写端,就形成了两个进程之间数据流动的一种方式。 - 有名管道
有名管道是一种半双工的通信方式,它允许无亲缘关系的进程间通信。 - fifo
fifo是一种先进先出队列,其类似于一个管道,只允许数据的单向流动,每个fifo都有一个名字,允许相关的进程访问同一个fifo。 - 信号量
信号量是一个计数器,可以用来控制多个线程对共享资源的访问。它不是用于交换大批数据,而用于多线程之间的同步,它常作为一个锁机制,防止某进程在访问资源时其他进程页访问该资源,因此,主要作为进程间以及同一个进程内不同线程之间的同步手段。 - 信号
信号是一种比较复杂的通信方式,同于通知进程某个事件已经发生。 - 消息队列
消息队列是消息的链表,存放在内核中并由消息队列标识符标识,消息队列克服了信号传递信息少,管道只能承载无格式字节流以及缓冲区大小受限等特点。消息队列是unix下不同进程之间可实现共享资源的一种机制,unix允许不同进程将格式化的数据流以消息队列的形式发送给任意进程。对消息队列具有操作权限的进程都可以使用msget完成对消息队列的操作控制。通过使用消息类型,进程可以按任何顺序读信息,货位消息安排优先级顺序。 - 共享内存
共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问.共享内存是最快的ipc(进程间通信)方式,它是针对其它进程间通信方式运行效率低而专门设计的.它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步与通信。 - 套接字(socket)
套接口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同进程及其间进程的通信.
通信方式的优缺点
进程之间的多种通信方法各自有各自的优点和缺点:
如果用户传递的信息较少或是需要通过信号来触发某些行为.前文提到的软中断信号机制不失为一种简捷有效的进程间通信方式.
但若是进程间要求传递的信息量比较大或者进程间存在交换数据的要求,那就需要考虑别的通信方式了。
无名管道简单方便,但局限于单向通信的工作方式.并且只能在创建它的进程及其子孙进程之间实现管道的共享。
有名管道虽然可以提供给任意关系的进程使用,但是由于其长期存在于系统之中,使用不当容易出错,所以普通用户一般不建议使用。
消息缓冲可以不再局限于父子进程,而允许任意进程通过共享消息队列来实现进程间通信,并由系统调用函数来实现消息发送和接收之间的同步,从而使得用户在使用消息缓冲进行通信时不再需要考虑同步问题,使用方便,但是消息队列中信息的复制需要额外消耗cpu的时间,不适宜于信息量大或操作频繁的场合。
共享内存针对消息缓冲的缺点改而利用内存缓冲区直接交换信息,无须复制,快捷、信息量大是其优点。但是共享内存的通信方式是通过将共享的内存缓冲区直接附加到进程的虚拟地址空间中来实现的。因此,这些进程之间的读写操作的同步问题操作系统无法实现。必须由各进程利用其他同步工具解决。另外,由于内存实体存在于计算机系统中,所以只能由处于同一个计算机系统中的诸进程共享,不方便网络通信。
不同的进程通信方式有不同的优点和缺点,因此,对于不同的应用问题,要根据问题本身的情况来选择进程间的通信方式。