#include <stdio.h>#include <unistd.h>#include <stdlib.h>int main(void){int n;int fd[2];pid_t pid;char line[3000];if(pipe(fd)<0)//pipeprintf("pipe error");if((pid=fork())<0)//fork{printf("fork error");}else if(pid>0){//parentclose(fd[0]);write(fd[1],"hello world\n",12);}else//child{close(fd[1]);n=read(fd[0],line,3000);write(STDOUT_FILENO,line,n);}exit(0);}
1、 管道概述及相關API應用
1.1 管道相關的關鍵概念
管道是Linux 支援的最初Unix IPC形式之一,具有以下特點:
管道是半雙工的,資料只能向一個方向流動;需要雙方通訊時,需要建立起兩個管道;
只能用於父子進程或者兄弟進程之間(具有親緣關係的進程);
單獨構成一種獨立的檔案系統:管道對於管道兩端的進程而言,就是一個檔案,但它不是普通的檔案,它不屬於某種檔案系統,而是自立門戶,單獨構成一種檔案系統,並且只存在與記憶體中。
資料的讀出和寫入:一個進程向管道中寫的內容被管道另一端的進程讀出。寫入的內容每次都添加在管道緩衝區的末尾,並且每次都是從緩衝區的頭部讀出資料。
1.2管道的建立:
#include <unistd.h>
int pipe(int fd[2])
該函數建立的管道的兩端處於一個進程中間,在實際應用中沒有太大意義,因此,一個進程在由pipe()建立管道後,一般再fork一個子進程,然後通過管道實現父子進程間的通訊(因此也不難推出,只要兩個進程中存在親緣關係,這裡的親緣關係指的是具有共同的祖先,都可以採用管道方式來進行通訊)。
1.3管道的讀寫規則:
管道兩端可分別用描述字fd[0]以及fd[1]來描述,需要注意的是,管道的兩端是固定了任務的。即一端只能用於讀,由描述字fd[0]表示,稱其為管道讀端;另一端則只能用於寫,由描述字fd[1]來表示,稱其為管道寫端。如果試圖從管道寫端讀取資料,或者向管道讀端寫入資料都將導致錯誤發生。一般檔案的I/O函數都可以用於管道,如close、read、write等等。
從管道中讀取資料:
如果管道的寫端不存在,則認為已經讀到了資料的末尾,讀函數返回的讀出位元組數為0;
當管道的寫端存在時,如果請求的位元組數目大於PIPE_BUF,則返回管道中現有的資料位元組數,如果請求的位元組數目不大於PIPE_BUF,則返回管道中現有資料位元組數(此時,管道中資料量小於請求的資料量);或者返回請求的位元組數(此時,管道中資料量不小於請求的資料量)。註:(PIPE_BUF在 include/linux/limits.h中定義,不同的核心版本可能會有所不同。Posix.1要求PIPE_BUF至少為512位元組,red hat 7.2中為4096)。