2013年1月26日 星期六

pipe

在linux底下,有anonymous pipe以及named pipe,兩者差異是anonymous pipe是不具名,所以在不同process之間無法共同使用,他存取主要藉由process的parent/child來存取,也就是在parent下先宣告一個pipe(),就可以同時在child下面共享;或者也可以由一個parent下的兩個child分享也是可以的
pipe的特性是,他是半雙工,也就是只有一個process通常只處理一端read(or write),另外一個process處理write(or read)的一端。現在許多新的系統也可以是全雙工的。

對pipe或許可以想像成是多個processes之間共享的queue,這樣就比較好理解了

richard stevens的書籍給出了許多的應用,比方說: process同步、filter...,可想而知pipe在unix/linux環境下的應用
在process建立parent/child關係,通常是透過fork(),所以動作變得有點麻煩,比方說

  • 宣告pipe()
  • fork()
  • 分別在parent, child中關閉
  • 必要的時候呼叫dup()/dup2()對應stdin跟stdout

popen()跟pclose()提供一個偷懶的方式XD,藉由popen等同fork()出一個process並且同時使用exec執行指令,跟著再把stdin跟stdout做好對應

底下是richard stevens的範例,pipe(fd[2])的參數[0]表示輸出,[1]表示輸入,程式就是將hello world由paretn送給child

#include <unistd.h>
#include <sys/types.h>

#define MAXLINE 80

int main(void){
    int n,fd[2];
    pid_t pid;
    char line[MAXLINE];
    if(pipe(fd)<0){
        printf("pipe failed!\n");
        exit(1);
    }   
    if( (pid=fork())<0 ){
        printf("fork error!\n");
        exit(1);
    }else if(pid>0){
        close(fd[0]);
        write(fd[1],"hello world\n",12);
    }else{
        close(fd[1]);
        n=read(fd[0],line,MAXLINE);
        write(STDOUT_FILENO,line,n);
    }   
    exit(0);
}
這裡必須要提到的是在一般stdin/stdout/stderr是FILE型態,而STDOUT_FILENO則是int型態,差別在於型態

沒有留言:

張貼留言