进程间的通讯方式有:管道、消息队列、信号量、共享内存
管道
管道是一种半双工的通信方式,数据只能单向流动;管道在内存中存取数据,磁盘上只保留管道的信息,故管道的大小恒为0。
管道分为pipe(无名管道)和fifo(有名管道)两种,除了建立、打开、删除的方式不同外,这两种管道几乎是一样的。他们都是通过内核缓冲区实现数据传输。
有名管道和无名管道的区别?
无名管道:
1、只能在有亲缘关系的进程(多为父子进程)间进行数据通信;
2、无名管道是基于进程存在的,只能在程序运行时被创建,每次使用都要创建管道。
有名管道:
1、可以在互不相关的进程之间实现通信;命名管道的名字对应于一个磁盘索引节点,但没有数据块,只是拥有一个名字和相应的访问权限,任何进程都可以通过文件名将其打开和进行读写。
2、可以使用命令创建管道,通过管道所在的路径名定位到该管道,两个进程间通信的时候直接使用该管道,不用再创建。在文件系统中可以查看到该管道文件,但大小恒为0;
消息队列
信号量
共享内存
共享内存允许两个或多个进程共享一个给定的存储区,这一段存储区可以被两个或两个以上的进程映射至自身的地址空间中,一个进程写入共享内存的信息,可以被其他使用这个共享内存的进程,通过一个简单的内存读取操作读出,从而实现了进程间的通信。
采用共享内存进行通信的一个主要好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝,对于像管道和消息队里等通信方式,则需要再内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次:一次从输入文件到共享内存区,另一次从共享内存到输出文件。
一般而言,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时在重新建立共享内存区域;而是保持共享区域,直到通信完毕为止,这样,数据内容一直保存在共享内存中,并没有写回文件。共享内存中的内容往往是在解除映射时才写回文件,因此,采用共享内存的通信方式效率非常高。
共享内存有两种实现方式:1、内存映射 2、共享内存机制
1、内存映射
内存映射 memory map机制使进程之间通过映射同一个普通文件实现共享内存,通过mmap()系统调用实现。普通文件被映射到进程地址空间后,进程可像访问普通内存一样对文件进行访问,不必再调用read/write等文件操作函数。
2、UNIX System V共享内存机制
IPC的共享内存指的是把所有的共享数据放在共享内存区域(IPC shared memory region),任何想要访问该数据的进程都必须在本进程的地址空间新增一块内存区域,用来映射存放共享数据的物理内存页面。
和前面的mmap系统调用通过映射一个普通文件实现共享内存不同,UNIX system V共享内存是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信。