- 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;
}