Changes between Version 8 and Version 9 of wade/linuxProgramming


Ignore:
Timestamp:
Jan 16, 2009, 5:19:53 PM (16 years ago)
Author:
wade
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • wade/linuxProgramming

    v8 v9  
    3737
    3838== Pipe ==
    39  * 範例:
     39 * 範例:pipe.c
    4040{{{
    4141// parent process 借由 fork() 產生一個跟自己一樣的 child process
     
    8282  }
    8383}
     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
    8495
    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
     99int 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
    92143== Reference ==
    93144 * [http://angkor.jazzbear.idv.tw/Linux_DivX/ Jazz 教學檔案]。