色yeye在线视频观看_亚洲人亚洲精品成人网站_一级毛片免费播放_91精品一区二区中文字幕_一区二区三区日本视频_成人性生交大免费看


無名管道系統調用

分享到:
           

    本文關鍵字: linux 管道通信,linux 進程通信方式 ,無名管道

    1.管道創建與關閉說明

    管道是基于文件描述符的通信方式,當一個管道建立時,它會創建兩個文件描述符fd[0]和fd[1],其中fd[0]固定用于讀管道,而fd[1]固定用于寫管道,如圖1所示,這樣就構成了一個半雙工的通道。


圖1 無名管道的讀寫機制

    管道關閉時只需將這兩個文件描述符關閉即可,可使用普通的close()函數逐個關閉各個文件描述符。

    2.管道創建函數

    創建管道可以通過調用pipe()來實現。表1列出了pipe()函數的語法要點。

表1 pipe()函數語法要點

所需頭文件 #include <unistd.h>
函數原型 int pipe(int fd[2])
函數傳入值 fd[2]:管道的兩個文件描述符,之后就可以直接操作這兩個文件描述符
函數返回值 成功:0
出錯:-1

    3.管道讀寫說明

    用pipe()函數創建的管道兩端處于一個進程中,由于管道是主要用于在不同進程間通信的,因此在實際應用中沒有太大意義。實際上,通常先是創建一個管道,再調用fork()函數創建一個子進程,該子進程會繼承父進程所創建的管道,這時,父子進程管道的文件描述符對應關系如圖2所示。


圖2 父子進程管道的文件描述符對應關系

    此時的關系看似非常復雜,實際上卻已經給不同進程之間的讀寫創造了很好的條件。父子進程分別擁有自己的讀寫通道,為了實現父子進程之間的讀寫,只需把無關的讀端或寫端的文件描述符關閉即可。例如,在圖3中將父進程的寫端fd[1]和子進程的讀端fd[0]關閉。此時,父子進程之間就建立起了一條“子進程寫入父進程讀取”的通道。


圖3 關閉父進程fd[1]和子進程fd[0]

    同樣,也可以關閉父進程的fd[0]和子進程的fd[1],這樣就可以建立一條“父進程寫入子進程讀取”的通道。另外,父進程還可以創建多個子進程,各個子進程都繼承了相應的fd[0]和fd[1]。這時,只需關閉相應端口就可以建立其各子進程間的通道。

    4.管道讀寫注意點

    管道讀寫需注意以下幾點:

    ● 只有在管道的讀端存在時,向管道寫入數據才有意義。否則,向管道寫入數據的進程將收到內核傳來的SIGPIPE信號(通常為Broken pipe錯誤)。

    ● 向管道寫入數據時,Linux將不保證寫入的原子性,管道緩沖區一有空閑區域,寫進程就會試圖向管道寫入數據。如果讀進程不讀取管道緩沖區中的數據,那么寫操作將會一直阻塞。

    ● 父子進程在運行時,它們的先后次序并不能保證。因此,為了保證父子進程已經關閉了相應的文件描述符,可在兩個進程中調用sleep()函數。當然這種調用不是很好的解決方法,在后面學到進程之間的同步機制與互斥機制后,請讀者自行修改本小節的實例程序。

    5.使用實例

    在本例中,首先創建管道,之后父進程使用fork()函數創建子進程,后通過關閉父進程的讀描述符和子進程的寫描述符,建立起它們之間的管道通信。

    /* pipe.c */
    #include <unistd.h>
    #include <sys/types.h>
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #define MAX_DATA_LEN 256
    #define DELAY_TIME 1

    int main()
    {
        pid_t pid;
        int pipe_fd[2];
        char buf[MAX_DATA_LEN];
        const char data[] = "Pipe Test Program";
        int real_read, real_write;

        memset((void*)buf, 0, sizeof(buf));
        if (pipe(pipe_fd) < 0) /* 創建管道 */
        {
            printf("pipe create error\n");
            exit(1);
        }
        if ((pid = fork()) == 0) /* 創建一個子進程 */
        {
            /* 子進程關閉寫描述符,并通過使子進程暫停1s等待父進程已關閉相應的讀描述符 */
            close(pipe_fd[1]);
            sleep(DELAY_TIME * 3);
            /* 子進程讀取管道內容 */
            if ((real_read = read(pipe_fd[0], buf, MAX_DATA_LEN)) > 0)
            {
                printf("%d bytes read from the pipe is '%s'\n", real_read, buf);
            }
            close(pipe_fd[0]); /* 關閉子進程讀描述符 */
            exit(0);
        }
        else if (pid > 0)
        {
            /* 父進程關閉讀描述符,并通過使父進程暫停1s等待子進程已關閉相應的寫描述符 */
            close(pipe_fd[0]);
            sleep(DELAY_TIME);
            if((real_write = write(pipe_fd[1], data, strlen(data))) != -1)
            {
                printf("Parent wrote %d bytes : '%s'\n", real_write, data);
            }
            close(pipe_fd[1]); /* 關閉父進程寫描述符 */
            waitpid(pid, NULL, 0); /* 收集子進程退出信息 */
            exit(0);
        }
    }

    將該程序交叉編譯,下載到開發板上的運行結果如下:

    $ ./pipe
    Parent wrote 17 bytes : 'Pipe Test Program'
    17 bytes read from the pipe is 'Pipe Test Program

    本文選自華清遠見嵌入式培訓教材《從實踐中學嵌入式Linux應用程序開發》

   熱點鏈接:

   1、Linux下進程間通信方式-管道
   2、Linux下進程間通信
   3、實驗:編寫守護進程
   4、實驗:編寫多進程程序
   5、Linux守護進程

更多新聞>> 

主站蜘蛛池模板: 久青草资源视频在线无码 | 极品少妇hdxx麻豆hdxx | 久久精品成人免费观看 | 久久精品人妻系列无码专区 | 内射后入在线观看一区 | 无码一区二区波多野结衣播放搜索 | 女人爽到高潮的免费AAAA | 日韩AV无码一区二区三区 | 四川少妇BBB凸凸凸BBB | 国产亚洲精品久久久美女 | 色噜噜久久综合伊人一本 | 无码人妻久久一区二区三区免费丨 | 国产精品99久久精品 | 人人草人人做人人爱 | 国产精品人人爱 | 撕开奶罩疯狂揉吮奶头 | 97国产婷婷综合在线视频 | 三年片在线观看大全 | 免费的av不用播放器的 | 四虎成人精品永久在线视频 | 呦交小U女国产精品视频 | 亚洲国产成人精品无码区四虎 | 日本一区二区三区精品视频在线观看 | 亚洲AV一二三又爽又色又色 | 小尤奈无码视频 | 中文日产幕无线码一区2023 | 亚洲狼人伊人中文字幕 | 国产精品青青草原免费无码 | 一本大道东京热无码 | 中文字幕第25页 | 国产对白视频 | 中文字幕av久久激情亚洲精品 | 欧美老熟妇欲乱高清视频 | 精品av国产一二三四区 | 色欲av蜜臀av久久浪潮av | 黄A无码片内射无码视频 | 欧美成人天天综合在线 | 1v1双性受整夜不拔bl | 日韩加勒比无码人妻系列 | 少妇搡BBBB搡BBB搡毛茸茸 | 中国女人FREE性HD国语 |