Linux 進程通信(無名管道)


無名管道
無名管道是半雙工的,就是對於一個管道來講,只能讀,或者寫。
無名管道只能在相關的,有共同祖先的進程間使用(即一般用戶父子進程)。
一個fork或者execve調用創建的子進程繼承了父進程的文件描述符。
打開和關閉管道
int pipe(int filedes[2]);
在你從一個管道中讀出或者寫入數據,這個管道必須存在。
如果成功建立了管道,則會打開兩個文件描述符,並把他們的值保存在一個整數數組中。
第一個文件描述符用於讀取數據,第二個文件描述符用於寫入數據。
管道的兩個文件描述符相當於管道的兩端,一端只負責讀數據,一端只負責寫數據 如果出錯返回
-1,同時設置errno 關閉一個文件描述符用close()函數
關閉一個管道的所有文件描述符等於關閉這個管道(不能讀不能寫) pipe()函數打開管道一般不會失敗
讀寫管道
讀寫管道與讀寫普通文件方式一樣,調用write與read函數即可。
幾乎不會在一個進程中打開一個管道僅供進程自己使用,管道是用來交換數據的。
因為一個進程已經能夠訪問它要通過管道共享的數據,和自己共享數據是沒有意義的。
試圖對一個管道的某一端同時進行讀寫操作是一個嚴重的錯誤。

 

//無名管道
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int arg, char * args[])
{
    //定義文件描述符數組
    int fdarr[2] = { 0 };
    int no = 0;
    int status;
    //create the conduit  創建一個管道 並且打開兩個文件描述符
    //管道中,第一個文件描述符只讀,第二個文件描述符只寫
    no = pipe(fdarr);
    if (no == -1)
    {
        printf("pipe() is failed ! message :%s\n", strerror(errno));
        return -1;
    }
    //創建父子進程
    pid_t child = fork();
    if (child == -1)
    {
        printf("system is game over !\n");
        return -1;
    }
    //定義緩存字符串數組
    char buf[100] = { 0 };
    if (child == 0)
    {
        /*
         管道和文件一樣,文件read函數以O_RDONLY方式打開也會阻塞,但是文件數據在本地,讀取非常快,感覺不到阻塞,
         但是管道以O_RDONLY方式打開,會阻塞進程,read()函數會等待管道另一端寫入數據,直到另一端關閉文件描述符
         */
        //關閉子進程中的寫文件描述符--對於父子進程共享文件描述符,只在單個進程中關閉,只能將文件描述符引用減一,
        //因為父子進程中,文件描述符被引用了兩次,所以需要在父子進程中分別關閉,才能使文件描述符引用次數減一
        close(fdarr[1]);
        while (read(fdarr[0], buf, sizeof(buf)) > 0)
        {
            printf("%s", buf);
            //清空緩存區
            memset(buf, 0, sizeof(buf));
        }
        //關閉子進程中讀文件描述符
        close(fdarr[0]);
    } else
    {
        //關閉父進程中的讀描述符
        close(fdarr[0]);
        //將鍵盤輸入數據寫入到管道中
        strcpy(buf,"fly on air!\n");
        write(fdarr[1], buf, strlen(buf));
        //關閉管道寫文件描述符
        close(fdarr[1]);
        //等待子進程結束
        wait(&status);
        printf("child process is close ! message :%d\n", WEXITSTATUS(status));
    }
    return 10;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM