| 84 | }}} |
| 85 | * FD[0] 負責 read pipe。FD[1] 負責 write pipe,換句話說,寫入 FD[1] 的資料可以由 FD[0] 讀取。 |
| 86 | * 寫入 FD[1] → [PIPE] → 讀取 FD[0] 。 |
| 87 | * 由於 FD 是 file descriptor, 非 file stream。所以為法使用 fread 和 fwrite。要使用 read 和 write 函式。 |
| 88 | * read() 會被 block 住,所以不用擔心 parent 會比 child 先結束,而導致 child 也跟著結束 (因為 child process 是依附著 parent process 而存在,依存關係可透過 pstree 查詢)。 |
| 89 | * 先使用 pipe(FD[2]),再使用 fork() 時,FD[2] 也會同時複製兩份,child 跟 parent 有各自的 FD[0]、FD[1],所以要記得關掉不必要的 FD ,兩個 processes 各自與 pipe 相接。 |
| 90 | * 範例:pipe2.c |
| 91 | {{{ |
| 92 | // parent process 借由 fork() 產生一個跟自己一樣的 child process |
| 93 | // 兩個 processes 間藉由 pipe 來傳遞資料 |
| 94 | // child → stdout → fd[1] → pipe → fd[0] → stdin → parent ,由 child 寫入資料至 pipe , parent 再由 pipe 接收資料並寫入 stdout |
85 | | }}} |
86 | | * FD[0] 負責 read pipe。FD[1] 負責 write pipe,換句話說,寫入 FD[1] 的資料可以由 FD[0] 讀取。 |
87 | | * 寫入 FD[1] → [PIPE] → 讀取 FD[0] 。 |
88 | | * 由於 FD 是 file descriptor, 非 file stream。所以為法使用 fread 和 fwrite。要使用 read 和 write 函式。 |
89 | | * read() 會被 block 住,所以不用擔心 parent 會比 child 先結束,而導致 child 也跟著結束 (因為 child process 是依附著 parent process 而存在,依存關係可透過 pstree 查詢)。 |
90 | | * 先使用 pipe(FD[2]),再使用 fork() 時,FD[2] 也會同時複製兩份,child 跟 parent 有各自的 FD[0]、FD[1],所以要記得關掉不必要的 FD ,兩個 processes 各自與 pipe 相接。 |
91 | | |
| 96 | #include <unistd.h> |
| 97 | #include <stdio.h> |
| 98 | |
| 99 | int main(void) |
| 100 | { |
| 101 | int n, fd[2]; |
| 102 | pid_t pid; |
| 103 | // 建立 pipe |
| 104 | if (pipe(fd) == 0) |
| 105 | { |
| 106 | // fork 創造一個 child process ,他與 parent 相同 |
| 107 | pid = fork(); |
| 108 | // 錯誤偵測,將結果寫入 stderr 中。 |
| 109 | if( pid == -1) |
| 110 | { |
| 111 | fprintf(stderr, "fore failure"); |
| 112 | exit(EXIT_FAILURE); |
| 113 | } |
| 114 | |
| 115 | // child process PID = 0 |
| 116 | if (pid == 0) |
| 117 | { |
| 118 | // 關閉標準輸入 |
| 119 | close(0); |
| 120 | // 將讀取 pipe 的 fd[0] 與 標準輸入連起來,則從 pipe 來的資料會成為一個標準輸入 |
| 121 | dup(fd[0]); |
| 122 | close(fd[0]); |
| 123 | close(fd[1]); |
| 124 | // 此時 more 會開起來等待標準輸入的資料,他會從標準輸入(pipe)讀取資料。 |
| 125 | execlp("more", "more", NULL); |
| 126 | } |
| 127 | // parent process PID ≠ 0 |
| 128 | else |
| 129 | { |
| 130 | // 關閉標準輸出 |
| 131 | close(1); |
| 132 | // 將寫入 pipe 的 fd[1] 與 標準輸出結合,則所有的標準輸出會自動寫入 pipe 中 |
| 133 | dup(fd[1]); |
| 134 | close(fd[0]); |
| 135 | close(fd[1]); |
| 136 | // 執行 ls ,並將結果寫入標準輸出,而標準輸出已經與 pipe 結合,所以結果會寫入 pipe 中 |
| 137 | execlp("ls", "ls", "-l", NULL); |
| 138 | } |
| 139 | } |
| 140 | } |
| 141 | }}} |
| 142 | * process 將自己的 stdout 寫入 write pipe ,將讀取 read pipe 轉換為本身的 stdin |