- pipe函数
管道函数
man pipe
#include <unistd.h>
int pipe(int pipefd[2]);参数介绍:pipefd读写文件描述符,0-代表读, 1-代表写
父子进程实现pipe通信,实现ps aux | grep bash
功能
经常出现的问题:
父进程认为写端存在,就有可能还有人发送数据,继续等待
所以尽量保持管道数据的流向保持一致,所以先在子进程关闭读端,
父进程关闭写端,这样管道流向就是 子进程写,父进程读。
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>int main() {int fd[2];pipe(fd);pid_t pid = fork();if(pid == 0) {// sonclose(fd[0]);dup2(fd[1], STDOUT_FILENO);execlp("ps", "ps", "aux", NULL);} else if(pid>0){// fatherclose(fd[1]);dup2(fd[0], STDIN_FILENO);execlp("grep", "grep", "bash", NULL);}return 0;
}
- pipe管道的行为
读管道
a.写端全部关闭, -- read读到0,相当于读到文件末尾b.写端没有全部关闭b1.有数据 -- read读到数据b2.没有数据 -- read阻塞 (fcntl函数可以更改为非阻塞)
写管道
a. 读端全部关闭, 产生一个信号,SIGPIPE(kill - 13),程序异常终止b. 读端没有全部关闭b1. 管道已满 --write阻塞b2. 管道未满 --write正常写入,
- pipe 管道的大小
通过ulimit -a
pipe size (512 bytes, -p) 8
- pipe 管道缺点
只能单向通信, 双向通信需要建立两个管道
只有血缘关系的进程才能通信 - 兄弟进程实现
ps aux | grep bash
功能
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {int fd[2];pipe(fd);pid_t pid;int i=0, n=2;for(i=0; i<n; i++) {pid = fork();if(pid == 0) {break;}}if(i == 0) {close(fd[0]);dup2(fd[1], STDOUT_FILENO);execlp("ps", "ps", "aux", NULL);} else if(i ==1 ) {close(fd[1]);dup2(fd[0], STDIN_FILENO);execlp("grep", "grep", "bash", NULL);} else if(i == 2) {close(fd[0]); close(fd[1]);wait(NULL);wait(NULL);}return 0;
}