管道通訊

什麼是管道?數組

 管道是單向的、先進先出的,它把一個進程的輸出和另外一個進程的輸入鏈接在一塊兒。一個進程(寫進程)在管道的尾部寫入數據,另外一個進程(讀進程)從管道的頭部讀出數據。函數

管道的分類this

管道包括無名管道和命名管道兩種,前者用於父進程和子進程間的通訊,後者可用於運行於同一系統或者跨系統中的任意兩個進程間的通訊。spa

無名管道由pipe( )函數建立:int pipe(int filedis[2]);操作系統

當一個管道被建立時,它會建立兩個文件描述符:filedis[0]用於讀管道,filedis[1]用於寫管道。管道通訊示意圖以下圖1所示:.net

                                                                     

 

                                                                                  管道通訊示意圖1指針

文件描述符: 內核(kernel)利用文件描述符(file descriptor)來訪問文件。文件描述符是非負整數。打開現存文件或新建文件時,內核會返回一個文件描述符。讀寫文件也須要使用文件描述符來指定待讀寫的文件。blog

管道關閉:關閉管道只是將兩個文件描述符關閉便可,可使用普通的close函數逐個關閉。繼承

無名管道讀寫:管道用於不一樣進程間通訊。一般先建立一個管道,再經過fork函數建立一個子進程,該子進程會繼承父進程建立的管道。注意事項:必須在系統調用fork()前調用pipe(),不然子進程將不會繼承文件描述符。不然,會建立兩個管道,由於父子進程共享同一段代碼段,都會各自調用pipe(),即創建兩個管道,出現異常錯誤。無名管道讀寫過程如圖2所示:進程

                                                                          

 

                                                                                              管道通訊示意圖2

管道的定義:int pipe(int filedes[2]);   

管道建立參數:int filedes[2]----一個數組

管道建立方式:pipe(fieldes)----建立一個管道,此管道函數的執行結果是建立管道的同時,也建立了一個管道讀取端,一個管道寫入端,讀取端賦予參數fields(0),寫入端賦予參數fields(1)​. 

管道建立的返回值-----1或者0,0表示建立成功,1表示建立失敗。

管道建立失敗的緣由保存在errno中,包括如下幾種:

​EMFILE 進程已用完文件描述詞最大量    

ENFILE 系統已無文件描述詞可用    

EFAULT 參數 filedes 數組地址不合法。​

無名管道經典實例

#include <stdio.h>

#include <unistd.h>

#include <sys/types.h>

#include <stdlib.h>

int main( void )

{

    int filedes[2];

    char buf[80];

    pid_t pid;

    pipe( filedes );

    if ( (pid=fork()) > 0 )

    {

        printf( "This is in the father process,here write a string to the pipe.\n" );

        char s[] = "Hello world , this is write by pipe.\n";

        write( filedes[1], s, sizeof(s) );

        close( filedes[0] );

        close( filedes[1] );

    }

    else

    {

        printf( "This is in the child process,here read a string from the pipe.\n" );

        read( filedes[0], buf, sizeof(buf) );

        printf( "%s\n", buf );

        close( filedes[0] );

        close( filedes[1] );

    }

    waitpid( pid, NULL, 0 );  

    return 0;

}

[root@localhost src]# gcc pipe.c

[root@localhost src]# ./a.out

This is in the child process,here read a string from the pipe.

This is in the father process,here write a string to the pipe.

Hello world , this is write by pipe.

fork以後,操做系統會複製一個與父進程徹底相同的子進程,雖然說是父子關係,可是在操做系統 看來,他們更像兄弟關係,這2個進程共享代碼空間,可是數據空間是互相獨立的,子進程數據空間中的內容是父進程的完整拷貝,指令指針也徹底相同,但只有一 點不一樣,若是fork成功,子進程中fork的返回值是0,父進程中fork的返回值是子進程的進程號,若是fork不成功,父進程會返回錯誤。
能夠這樣想象,2個進程一直同時運行,並且步調一致,在fork以後,他們分別做不一樣的工做,也就是分岔了。這也是fork爲何叫fork的緣由。
至於那一個最早運行,可能與操做系統有關,並且這個問題在實際應用中並不重要,若是須要父子進程協同,能夠經過原語的辦法解決。

#include ;

#include ;

#include <stdio.h>

#include <unistd.h>

#include <sys/types.h>

#include <stdlib.h>

main (){        

pid_t pid;        

pid=fork();        

if (pid < 0)                

printf("error in fork!");        

else if (pid == 0)                

printf("i am the child process, my process id is %d\n",getpid());        

else                

printf("i am the parent process, my process id is %d\n",getpid());

}

結果是
[root@localhost c]# ./a.out
i am the child process, my process id is 4286
i am the parent process, my process id is 4285

也能夠參考一篇文章:http://blog.csdn.net/wc7620awjh/article/details/7709581

相關文章
相關標籤/搜索