無名管道的局限性:
無名管道和有名管道的區別, 1)雖然某些系統提供全雙工管道,但是為了可移植性,不能預先假定系統支持全雙工管道
2)管道只能在具有公共祖先的兩個進程間使用。(一般都是父子進程)
無名管道是調用pipe函數創建的:
#include <unistd.h> ? ??
int pipe(int fd[2]); ? ?
返回值:若成功,返回0;若出錯,返回-1?
由參數fd返回兩個文件描述符:fd[0]為讀而打開,fd[1]為寫而打開。fd[1]的輸出是fd[0]的輸入。
進程通常會調用pipe,接著調用fork,從而創建從父進程到子進程的IPC通道。
#? 管道通訊是單向的(只創建一個管道),有固定的讀端和寫端。
#? 數據被進程從管道讀出后,在管道中該數據就不存在了。
#? 當進程去讀取空管道的時候,進程會阻塞。
#? 當進程往滿管道寫入數據時,進程會阻塞。(管道有容量大小)
fork之后做什么取決于想要的數據流方向:
從父進程到子進程的管道,父進程關閉管道的讀端(fd[0]),子進程關閉寫段(fd[1]);
從子進程到父進程的管道,父進程關閉管道的寫端(fd[1]),子進程關閉讀端(fd[0])。
//單向通信:父進程到子進程的管道
1 #include <stdio.h> 2 #include <unistd.h> 3 4 int main() 5 { 6 int fd[2]; 7 pid_t pid; 8 char content[1024] = {}; 9 10 if(pipe(fd) < 0) 11 perror("pipe error"); 12 if((pid = fork()) < 0) 13 { 14 perror("fork error"); 15 } 16 else if(pid > 0) /*parent*/ 17 { 18 close(fd[0]); //關閉父進程的讀端 19 write(fd[1], "this is apple", 13); 20 } 21 else /*child*/ 22 { 23 close(fd[1]); //關閉子進程的寫端 24 read(fd[0], content, 1024); 25 printf("%s\n", content); 26 } 27 28 return 0; 29 }
//雙向通信:方法就是創建兩個管道
1 #include <stdio.h> 2 #include <unistd.h> 3 4 int main() 5 { 6 int fd1[2], fd2[2]; 7 pid_t pid; 8 char content1[1024] = {}; 9 char content2[1024] = {}; 10 11 if(pipe(fd1) < 0) 12 perror("pipe error"); 13 14 if(pipe(fd2) < 0) 15 perror("pipe error"); 16 17 if((pid = fork()) < 0) 18 { 19 perror("fork error"); 20 } 21 else if(pid > 0) /*parent*/ 22 { 23 close(fd1[0]); //關閉 管道一 父進程的讀端 24 write(fd1[1], "this is pipe1 data!", 19); 25 26 close(fd2[1]); //關閉 管道二 父進程的寫端 27 read(fd2[0], content2, 1024); 28 29 printf("%s\n", content2); 30 } 31 else /*child*/ 32 { 33 close(fd1[1]); //關閉 管道一 子進程的寫端 34 read(fd1[0], content1, 1024); 35 36 printf("%s\n", content1); 37 38 close(fd2[0]); //關閉 管道二 子進程的讀端 39 write(fd2[1], "this is pipe2 data!", 19); 40 } 41 42 return 0; 43 }
?