管道,其本質是一個偽文件(實為內核緩沖區);由兩個文件描述符引用,一個表示讀端、一個表示寫端;規定數據從管道的寫端流入,讀端流出。
管道的原理:管道實為內核使用環形隊列機制,借助內核緩沖區(4k)實現。
必須用于有血緣關系的進程
管道的局限性:
?
① 數據自己讀不能自己寫。
?
② 數據一旦被讀走,便不在管道中存在,不可反復讀取。
?
③ 由于管道采用半雙工通信方式。因此,數據只能在一個方向上流動。
?
④ 只能在有公共祖先的進程間使用管道。
常見的通信方式有,單工通信、半雙工通信、全雙工通信。
?
pipe,創建管道
int pipe(int pipefd[2]);??成功:0;失敗:-1,設置errno
函數調用成功返回r/w兩個文件描述符。無需open,但需手動close。規定:fd[0] → r; fd[1] → w,就像0對應標準輸入,1對應標準輸出一樣。向管道文件讀寫數據其實是在讀寫內核緩沖區。
示例:
1 #include <stdio.h> 2 #include <unistd.h> 3 4 int main(void) 5 { 6 int fd[2]; 7 pid_t pid; 8 9 int ret = pipe(fd); //定義管道 父進程占用兩端 10 if(ret == -1) 11 { 12 perror("pipe error"); 13 exit(1); 14 } 15 pid = fork(); 16 if(pid == -1) 17 { 18 perror("fork error"); 19 exit(1); 20 }else if(pid == 0)//子進程(也占用了兩端) 子進程讀,將寫端關閉 默認0讀 1寫 21 { 22 close(fd[1]); 23 char buf[1024]; 24 ret read(fd[0], buf, sizeof(buf)); //將管道看作文件操作 25 if(ret == 0){ 26 printf("----\n"); //讀完 27 } 28 write(STDOUT_FILENO,buf, ret); //寫到屏幕 29 }else{ //父進程 關閉讀端 30 close(fd[0]); 31 char *str = "hello pipe\n"; 32 write(fd[1],"hello pipe\n", strlen("hello pipe\n")); 33 } 34 return 0; 35 }
?