IPC(InterProcess Communication)进程间通信.为啥没有进程间通信,这是因为进程间都是同步的关系,不需要通信.
1.管道
1.1管道特点:
(1)半双工的(即数据只能在一个方向上流动),某些系统提供全双工的管道.
(2)管道只能在具有公共祖先的两个进程之间使用.通常,一个管道由一个进程创建,在进程调用fork后,这个管道就能在父子进程之间通信了.
1.2使用:
(1)在管道中键入一条命令,让shell执行,shell会为每一条命令单独创建一个进程,然后用管道将浅一条命令进程的标准输出与后一条命令的标准输入链接.
(2)管道通过调用pipe函数来创建:
#include<unistd.h> int pipe(int fd[2]);
#include "apue.h" int main(void) { int n; int fd[2]; pid_t pid; char line[MAXLINE]; if (pipe(fd) < 0) err_sys("pipe error"); if ((pid = fork()) < 0){ err_sys("fork error"); }else if(pid > 0){ /* parent */ close(fd[0]); write(fd[1], "hello son, this is from your dad ", 33); }else{ /* child */ close(fd[1]); n = read(fd[0], line, MAXLINE); write(STDOUT_FILENO, line, n); } exit(0); }
1.3原理:
首先父进程创建一个父进程到父进程的管道,然后fork得到子进程,子进程同样得到了父进程的管道.然后父进程关闭读端,子进程关闭写端.从而得到了一条父进程写 子进程读的管道.
1.4 popen和pclose:
常见的操作是创建一个链接到另一个进程的管道,然后读其输出或向其输入端发送数据,为此,标准I/O库提供了两个函数popen和pclose来实现这样的操作:创建一个管道,fork一个子进程,关闭未使用的管道端,执行一个shell运行命令,然后等待命令终止.
2.FIFO
FIFO有时被称为命名管道.未命名的管道只能在两个相关的进程之间使用,而且这两个相关进程还要有一个共同的创建他们的祖先.
但是FIFO,不相关的进程也可以交换数据.
FIFO是一种文件类型.创建FIFO类似于创建一个文件.
2.1用途:
(1)shell命令使用FIFO将数据从一条管道传送到另一条时,无需创建中间文件;
用FIFO复制输出流
(2)客户进程-服务器进程应用程序中,FIFO用作汇聚点,在客户进程和服务器进程二者之间传递数据.
使用FIFO进行客户进程-服务器进程通信
XSI IPC(消息队列信号量或者共享存储器)
标识符和键:
每个内核中的IPC结构(消息队列信号量或者共享存储器)都用一个非负整数的标识符加以引用.
每个IPC对象都与一个键(key)相关联,将这个键作为该对象的外部名.
权限结构:
3 消息队列
消息队列是消息的链接表,存储在内核中,由消息队列标识符标识.与命名管道一样,消息队列可以在不相关进程之间进行通信.二者都是通过发送和接收的方式来传递数据的.
在命名管道中 发送数据write 接收数据read
在消息队列中 发送数据msgsnd 接收数据msgrcv
他们对每个数据都有一个最大长度的限制.
4 信号量
信号量是一个计数器,他与IPC机构(管道 FIFO 消息队列)不同.
信号量主要用来为多个进程提供对共享数据对象的访问.
为了获得共享资源,进程需要执行下列操作:
(1)测试控制该资源的信号量.
(2)若此信号量的值未正,则进程可以是使用该共享资源.在这种情况下,进程会将信号量-1,表示它使用了一个资源单位.
(3)否则,若信号量=0,则进程进入休眠状态,直至信号量>0
信号量值的测试以及减1操作应该是原子操作.
4.1分类:
(1)内核信号量, 由内核控制路径使用
(2)用户态进程使用的信号量,又分POSIX信号量和SYSTEM V信号量。
POSIX信号量又分为有名信号量和无名信号量。
有名信号量,其值保存在文件中, 所以它可以用于线程也可以用于进程间的同步。
无名信号量,其值保存在内存中。
信号量 记录锁和互斥量的时间比较:
如果在多个进程间共享一个资源,可以使用这3种技术中的一种来协调访问.
5 共享存储:
共享存储允许两个或以多个进程共享一个给定的存储区.(同一逻辑内存)因为数据不需要在客户进程和服务器进程之间复制,所以是最快的一种IPC.
有一个数据同步的问题,就是在服务端在向内存里面写数据完成之前,不应当又客户端取数据,通常,信号量用于同步共享存储访问.(也可以使用 记录锁 或 互斥量)