久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久


無名管道系統調用

分享到:
           

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

    1.管道創建(jian)與關閉說(shuo)明

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


圖1 無(wu)名管道的(de)讀寫機制

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

    2.管道(dao)創(chuang)建函數

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

表1 pipe()函數語法要點

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

    3.管道(dao)讀寫說明

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


圖(tu)2 父子進程管道(dao)的文(wen)件(jian)描述符(fu)對應關系

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


圖3 關閉父進(jin)程(cheng)fd[1]和子進(jin)程(cheng)fd[0]

    同樣,也(ye)可(ke)以關(guan)閉父進(jin)程(cheng)(cheng)(cheng)的(de)fd[0]和子進(jin)程(cheng)(cheng)(cheng)的(de)fd[1],這(zhe)樣就可(ke)以建(jian)立(li)一條“父進(jin)程(cheng)(cheng)(cheng)寫入子進(jin)程(cheng)(cheng)(cheng)讀(du)取(qu)”的(de)通道(dao)。另(ling)外(wai),父進(jin)程(cheng)(cheng)(cheng)還(huan)可(ke)以創建(jian)多個(ge)子進(jin)程(cheng)(cheng)(cheng),各個(ge)子進(jin)程(cheng)(cheng)(cheng)都繼(ji)承了(le)相(xiang)應的(de)fd[0]和fd[1]。這(zhe)時,只需關(guan)閉相(xiang)應端(duan)口就可(ke)以建(jian)立(li)其(qi)各子進(jin)程(cheng)(cheng)(cheng)間的(de)通道(dao)。

 &nbsp;  4.管道(dao)讀寫(xie)注意(yi)點(dian)

    管(guan)道讀(du)寫需注意以下幾點:

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

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

    ● 父子(zi)進(jin)程在(zai)運行時(shi),它們的(de)(de)先后(hou)次序(xu)并(bing)不能(neng)保證(zheng)。因此,為了保證(zheng)父子(zi)進(jin)程已經關閉(bi)了相應的(de)(de)文件描述符,可在(zai)兩(liang)個進(jin)程中調(diao)(diao)用sleep()函數(shu)。當(dang)然這種調(diao)(diao)用不是(shi)很好的(de)(de)解(jie)決方法,在(zai)后(hou)面(mian)學(xue)到進(jin)程之間的(de)(de)同步(bu)機制(zhi)與互斥機制(zhi)后(hou),請讀者自行修改本(ben)小節(jie)的(de)(de)實例程序(xu)。

    5.使用實(shi)例

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

    /* 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);
        }
    }

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

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

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

   熱點(dian)鏈接:

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

更多新聞>>