linux环境下,各进程相互独立,如果想要交换两个进程之间的数据,需要通过内核,在内存中提供一个缓存区,一个进程往缓存区中写数据,一个往缓存区读数据,内核提供的这种机制称为进程间通信(IPC),常见的进程通信有四种:管道(最简单),信号(开销最小),共享映射区(无血缘关系),本地套接字(最稳定)。
(1)管道
管道的特点:本质是一个伪文件(内核缓冲区),两个文件描述符引用(读端和写端),写端写入,读端读出。
管道的原理及实质:内核使用环形队列机制,借助内核缓冲区实现。
管道的缺点:1)数据自己读不能自己写;2)数据被读走,不在管道存在;3)半双工通信(数据读写不能同时,数据流向唯一);4)有血缘关系的进程间;
创建管道pipe函数:
函数头文件及原型:函数参数为输入参数 成功调用返回0 ,失败返回-1
函数调用成功返回r/w两个文件,无需open,但是需要手动close,其中pipefd[0] -->r,pipefd[1]-->w,可根据读写要求关闭pipe的一端来实现进程通信;
管道中的读写情况有四种:
1)读管道时 1.管道有数据,read返回实际读到的字节数;
2.管道中无数据
1>管道写端全部关闭,read返回0,表示读到文件末尾;
2>官渡写端没有关闭,read阻塞等待数据来;
2)写管道时 1.管道读端全部关闭,进程异常终止
2.管道读端没有关闭
1>管道已满,write阻塞
2>管道未满,write写入数据,返回实际写入的字节数。
使用管道实现父子通信,实现ls |wc -l ,父进程实现ls.子进程实现wc -l;
使用管道实现兄弟进程通信,兄:ls 弟 wc -l 父 等待回收子进程
(2)FIFO 命名管道(不想关的进程也可以进行通信)
特点:属于基础文件类型的一种,FIFO文件在磁盘上没有数据块,只有用来表示内核的一条通道,各进程可以打开这个文件进行read/write。
创建方式:命令 mkfifo 管道名
库函数 int mkfifo(const char*pathname,mode_t mode); 成功:0 失败 -1;
使用mkfifo创建了一个FIFO,就可以用open打开它,常见的i/o函数都可以作用于fifo.
如博客https://blog.csdn.net/superywf/article/details/73438465的例子使用如下: