一、管道
1、父子进程之间并不共享数据段和堆栈段,它们之间是通过管道进行通信的。
2、管道的特点:
1)数据只能由一个进程流向另一个进程(其中一个读管道,一个写管道);如果要进行双工通信,则需要建立两个管道。
2)管道只能用于父子进程或者兄弟进程间通信,也就是说管道只能用于具有亲缘关系的进程间通信;
3)管道没有名字(无名管道),管道的缓冲区大小是受限制的;管道所传输的是无格式的字节流。
3、写入的数据每次都添加到管道缓冲区的末尾,读数据的时候都是从缓冲区的头部读出数据的。
4、管道由**pipe()**函数创建,头文件及函数原型为:
#include<unistd.h>
int pipe(int fd[2]);
5、一个进程在由pipe()创建管道后,一般再使用fork建立一个子进程,然后通过管道实现父子进程间的通信。管道两端可分别用描述字fd[0]以及fd[1]来描述。管道的两端是固定了任务的,即一段只能用于读,由描述字fd[0]表示,称其为管道读端;另一端则只能用于写,由描述字fd[1]来表示,称其为管道写端;一般文件的I/O函数都可以用于管道,如close、read、write等。
6、父子进程分别拥有自己的读写通道,为了实现父子进程之间的读写,只需把无关的读端或写端的文件描述符关闭即可。
7、有名管道提供了一个路径名与之关联,以FIFO的文件形式存在于文件系统中。这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间),因此,通过FIFO不相关的进程也能交换数据。
8、有名管道具有以下特点:
1)它可以使互不相关的两个进程间实现彼此通信;
2)该管道可以通过路径名来指出,并且在文件系统中是可见的;在建立了管道之后,两个进程就可以把它当作普通文件一样进行读写操作,使用非常方便;
3)FIFO严格地遵循先进先出规则,对管道及FIFO的读操作总是从开始处返回数据,对它们的写操作则是把数据添加到末尾。
二、消息队列
1、消息队列用于运行于同一台机器上的进程间通信,是一个在系统内核中用来保存消息的队列,它在系统内核中是以消息链表的形式出现。消息链表中节点的结构用msg声明。
2、在命名管道中,发送数据用write函数,接收数据用read函数,则在消息队列中,发送数据用msgsnd函数,接收数据用msgrcv函数,而且它们对每个数据都有一个最大长度的限制。
3、与命名管道相比,消息队列的优势在于:
1)消息队列也可以独立于发送和接收进程而存在,从而消除了在同步命名管道的打开和关闭时可能产生的困难;
2)可以同时通过发送消息以避免命名管道的同步和阻塞问题,而不需要由进程自己来提供同步方法;
3)接收程序可以通过消息类型有选择地接收数据,而不是像命名管道中那样,只能默认地接收。
三、共享内存
1、共享内存就是允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排在同一段物理内存中。进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C 语言函数malloc 分配的内存一样。而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程。
不过,共享内存并未提供同步机制,也就是说,在第一个进程对共享内存的写操作结束之前,并无自动机制可以阻止第二个进程对它进行读取。所以通常需要用其他的机制来同步对共享内存的访问。
2、共享内存的优缺点:
1)优点:使用共享内存进行进程间的通信非常方便,而且函数的接口也简单,数据的共享还使进程间的数据不用传送,而是直接访问内存,也加快了程序的效率。同时,它也不像无名管道那样要求通信的进程有一定的父子关系。
2)缺点:共享内存没有提供同步的机制,这使得在使用共享内存进行进程间通信时,往往要借助其他的手段来进行进程间的同步工作,可以使用信号量来进行进程的同步,因为对信号量的操作都是原子性的。
四、信号量
五、ipcs命令
1、ipcs是一个UNIX/Linux的命令,用于报告系统的消息队列、信号量、共享内存等。
2、ipcs -a 用于列出本用户所有相关的ipcs参数。
3、ipcs -q用于列出进程中的消息队列
4、ipcs -s 用于列出所有的信号量
5、ipcs -m 用于列出所有的共享内存信息
6、ipcs -l 用于列出系统的限额
7、ipcs -t 用于列出最后的访问时间
8、ipcs -u 用于列出当前的使用情况