1. 程式人生 > >程序間通訊-管道(PIPE)和有名管道(FIFO)

程序間通訊-管道(PIPE)和有名管道(FIFO)

1.2有名管道的建立



該函式的第一個引數是一個普通的路勁名,也就是建立後FIFO的名字。第二個引數與開啟普通檔案的open()函式中的mode引數相同。如果mkfifo的一個引數是一個已經存在路勁名時,會返回EEXIST錯誤,所以一般典型的呼叫程式碼首先會檢查是否返回該錯誤,如果確實返回該錯誤,那麼只要呼叫開啟FIFO的函式就可以了。 1.3有名管道的開啟規則 有名管道比無名管道多了一個開啟操作:open FIFO的開啟規則: 如果當前開啟操作時為讀而開啟FIFO時,若已經有相應程序為寫而開啟該FIFO,則當前開啟操作將成功返回;否則,可能阻塞到有相應程序為寫而開啟該FIFO(當前開啟操作設定了阻塞標誌
);或者,成功返回(當前開啟操作沒有設定阻塞標誌)。
如果當前開啟操作時為寫而開啟FIFO時,如果已經有相應程序為讀而開啟該FIFO,則當前開啟操作將成功返回;否則,可能阻塞直到有相應程序為讀而開啟該FIFO(當前開啟操作設定了阻塞標誌);或者,返回ENIO錯誤(當期開啟操作沒有設定阻塞標誌)。 案例: A.open for  write

點選(此處)摺疊或開啟

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <
    errno.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <fcntl.h>
  8. int main(int argc,char *argv[])
  9. {
  10.     int fd;
  11.     if(argc < 2)
  12.     {
  13.         fprintf(stderr,"usage : %s argv[1].\n",argv[0]);
  14.         exit(EXIT_FAILURE);
  15.     }
  16.     if(mkfifo(
    argv[1],0666) < 0 && errno != EEXIST)
  17.     {
  18.         fprintf(stderr,"Fail to mkfifo %s : %s.\n",argv[1],strerror(errno));
  19.         exit(EXIT_FAILURE);
  20.     }
  21.     if((fd = open(argv[1],O_WRONLY)) < 0)
  22.     {
  23.         fprintf(stderr,"Fail to open %s : %s.\n",argv[1],strerror(errno));
  24.         exit(EXIT_FAILURE);
  25.     }
  26.     printf("open for write success.\n");
  27.     return 0;
  28. }

B.open for read


點選(此處)摺疊或開啟

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <errno.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <fcntl.h>
  8. int main(int argc,char *argv[])
  9. {
  10.     int fd;
  11.     if(argc < 2)
  12.     {
  13.         fprintf(stderr,"usage : %s argv[1].\n",argv[0]);
  14.         exit(EXIT_FAILURE);
  15.     }
  16.     if(mkfifo(argv[1],0666) < 0 && errno != EEXIST)
  17.     {
  18.         fprintf(stderr,"Fail to mkfifo %s : %s.\n",argv[1],strerror(errno));
  19.         exit(EXIT_FAILURE);
  20.     }
  21.     if((fd = open(argv[1],O_RDONLY)) < 0)
  22.     {
  23.         fprintf(stderr,"Fail to open %s : %s.\n",argv[1],strerror(errno));
  24.         exit(EXIT_FAILURE);
  25.     }
  26.     printf("open for read success.\n");
  27.     return 0;
  28. }

探究發現,如果open時沒有使用O_NONBLOCK引數,我們發現不論讀端還是寫端先開啟,先開啟者都會阻塞,一直阻塞到另一端開啟。 讀者自己可以探究,如果open時使用了O_NONBLOCK引數,此時開啟FIFO 又會是什麼情況? 1.4有名管道的讀寫規則 A.從FIFO中讀取資料 約定:如果一個程序為了從FIFO中讀取資料而以阻塞的方式開啟FIFO, 則稱核心為該程序的讀操作設定了阻塞標誌 <1>如果有程序為寫而開啟FIFO,且當前FIFO內沒有資料,則對於設定了阻塞標誌的讀操作來說,將一直阻塞。對於沒有設定阻塞標誌讀操作來說返回-1,當前errno值為EAGAIN,提醒以後再試。 <2>對於設定阻塞標誌的讀操作說,造成阻塞的原因有兩種:當前FIFO內有資料,但有其他程序正在讀這些資料;另外就是FIFO內沒有資料。解阻塞的原因則是FIFO中有新的資料寫入,不論寫入資料量的大小,也不論讀操作請求多少資料量。 <3>如果沒有程序寫開啟FIFO,則設定了阻塞標誌的讀操作會阻塞 <4>如果寫端關閉,管道中有資料讀取管道中的資料,如果管道中沒有資料讀端將不會繼續阻塞,此時返回0。 注意:如果FIFO中有資料,則設定了阻塞標誌的讀操作不會因為FIFO中的位元組數小於請求讀的位元組數而阻塞,此時,讀操作會返回FIFO中現有的資料量。 B.向FIFO中寫入資料 約定:如果一個程序為了向FIFO中寫入資料而阻塞開啟FIFO,那麼稱該程序內的寫操作設定了阻塞標誌。 對於設定了阻塞標誌的寫操作: <1>當要寫入的資料量不大於PIPE_BUF時,linux將保證寫入的原子性。如果此時管道空閒緩衝區不足以容納要寫入的位元組數,則進入睡眠,直到當緩衝區中能夠容納寫入的位元組數時,才開始進行一次性寫操作。 <2>當要寫入的資料量大於PIPE_BUF時,Linux將不再保證寫入的原子性。FIFO緩衝區一有空閒區域,寫程序就會試圖向管道寫入資料,寫操作在寫完所有請求寫的資料後返回。 對於沒有設定阻塞標誌的寫操作: <1>當要寫入的資料量大於PIPE_BUF時,linux將不再保證寫入的原子性。在寫滿所有FIFO空閒緩衝區後,寫操作返回。 <2>當要寫入的資料量不大於PIPE_BUF時,linux將保證寫入的原子性。如果當前FIFO空閒緩衝區能夠容納請求寫入的位元組數,寫完後成功返回;如果當前FIFO空閒緩衝區不能夠容納請求寫入的位元組數,則返回EAGAIN錯誤,提醒以後再寫。 注意:只有讀端存在,寫端才有意義。如果讀端不在,寫端向FIFO寫資料,核心將向對應的程序傳送SIGPIPE訊號(預設終止程序); 案例一、 write to FIFO

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <errno.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <fcntl.h>
  8. #define MAX 655360
  9. int main(int argc,char *argv[])
  10. {
  11.     int n,fd;
  12.     char buf[MAX];
  13.     if(argc < 2)
  14.     {
  15.         fprintf(stderr,"usage : %s argv[1].\n",argv[0]);
  16.         exit(EXIT_FAILURE);
  17.     }
  18.     if(mkfifo(argv[1],0666) < 0 && errno != EEXIST)
  19.     {
  20.         fprintf(stderr,"Fail to mkfifo %s : %s.\n",argv[1],strerror(errno));
  21.         exit(EXIT_FAILURE);
  22.     }
  23.     if((fd = open(argv[1],O_WRONLY )) < 0)
  24.     {
  25.         fprintf(stderr,"Fail to open %s : %s.\n",argv[1],strerror(errno));
  26.         exit(EXIT_FAILURE);
  27.     }
  28.     printf("open for write success.\n");
  29.     while(1)
  30.     {
  31.         printf(">");
  32.         scanf("%d",&n);
  33.         n = write(fd,buf,n);
  34.         printf("write %d bytes.\n",n);
  35.     }
  36.     exit(EXIT_SUCCESS);
  37. }

read from FIFO

點選(此處)摺疊或開啟

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <errno.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <fcntl.h>
  8. #define MAX 655360
  9. int main(int argc,char *argv[])
  10. {
  11.     int fd,n;
  12.     char buf[MAX];
  13.     if(argc < 2)
  14.     {
  15.         fprintf(stderr,"usage : %s argv[1].\n",argv[0]);
  16.         exit(EXIT_FAILURE);
  17.     }
  18.     if(mkfifo(argv[1],0666) < 0 && errno != EEXIST)
  19.     {
  20.         fprintf(stderr,"Fail to mkfifo %s : %s.\n",argv[1],strerror(errno));
  21.         exit(EXIT_FAILURE);
  22.     }
  23.     if((fd = open(argv[1],O_RDONLY )) < 0)
  24.     {
  25.         fprintf(stderr,"Fail to open %s : %s.\n",argv[1],strerror(errno));
  26.         exit(EXIT_FAILURE);
  27.     }
  28.     printf("open for read success.\n");
  29.     while(1)
  30.     {
  31.         printf(">");
  32.         scanf("%d",&n);
  33.         n = read(fd,buf,n);
  34.         printf("Read %d bytes.\n",n);
  35.     }

    相關推薦

    程序通訊-管道PIPE有名管道FIFO

    1.2有名管道的建立 該函式的第一個引數是一個普通的路勁名,也就是建立後FIFO的名字。第二個引數與開啟普通檔案的open()函式中的mode引數相同。如果mkfifo的一個引數是一個已經存在路勁名時,會返回EEXIST錯誤,所以一般典型的呼叫程式碼首先會檢查是否返回該錯誤,如果確實返回該錯誤,

    Linux程序通訊--無名管道pipe有名管道FIFO通訊

    管道通訊 管道是單向的、先進先出的,它把一個程序的輸出和另一個程序的輸入連線在一起。一個程序(寫程序)在管道的尾部寫入資料,另一個程序(讀程序)從管道的頭部讀出資料 管道建立 管道包括無名管道和有名管道兩種,前者用於父程序和子程序的通訊,後者可用於運行於同一系統中的任意兩個程序間

    Linux高階程式設計基礎——程序通訊之用sigqueue函式sigaction函式實現訊號的安裝與傳送

    程序間通訊之用sigqueue函式和sigaction函式實現訊號的安裝與傳送 程序A向程序B傳送SIGUSR1訊號; 程序B收到訊號後,列印字串“receive SIGUSR1”; 要求用sigqueue函式和sigaction函式實現以上功能; /這個實

    程序通訊--popen函式pclose函式blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=25940216&id=3206312

    因為一個普遍的操作是為另一個程序建立一個管道,或者讀它的輸出或向它傳送輸入,所以標準I/O庫歷史上提供了popen和pclose函式。這兩 個函式處理我們自己一直在做的髒活:建立一個管道、fork一個子程序、關閉管道無用的端,執行一個外殼來執行這個命令,等待命令終止。 #include <st

    Linux程序通訊分類 以及 pipe的原理實現

    一個大型的應用系統,往往需要眾多程序協作,程序(Linux程序概念見附1)間通訊的重要性顯而易見。本系列文章闡述了Linux環境下的幾種主要程序間通訊手段,並針對每個通訊手段關鍵技術環節給出詳細例項。為達到闡明問題的目的,本文還對某些通訊手段的內部實現機制進行了分析。

    程序程序通訊 —— Queue佇列Pipe管道

    目錄 程序間通訊 佇列  概念介紹 方法介紹 程式碼例項 生產者消費者模型 JoinableQueue([maxsize])  管道(瞭解) 程序間通訊 IPC(Inter-Process Communication) 佇列&nbs

    Linux系統程式設計——程序通訊管道pipe

    管道的概述 管道也叫無名管道,它是是 UNIX 系統 IPC(程序間通訊) 的最古老形式,所有的 UNIX 系統都支援這種通訊機制。 無名管道有如下特點: 1、半雙工,資料在同一時刻只能在一個方向上流動。 2、資料只能從管道的一端寫入,從另一端讀出。

    程序通訊管道pipe

    管道的概述 管道也叫無名管道,它是是 UNIX 系統 IPC(程序間通訊) 的最古老形式,所有的 UNIX 系統都支援這種通訊機制。 無名管道有如下特點: 1、半雙工,資料在同一時刻只能在一個方向上流動。 2、資料只能從管道的一端寫入,從另一端讀出。 3、寫入

    程序通訊命名管道fifo

    要學習命名管道,我們必須首先對管道的特性有一定的瞭解,管道特性以及匿名管道連結 命名管道:管道的一個限制就是隻能用在親緣程序之間,如果我們想在不相關的程序間進行資料交換,可以使用FIFO檔案來進行,它叫做命名管道。 命名管道:檔案系統可見,是一個特殊型別(管道型別)的檔案。命名管

    Linux:程序通訊匿名管道命名管道共享記憶體,訊息佇列,訊號量

    目錄 程序間通訊的介紹 管道 匿名管道 原理: 程式碼實現 匿名管道特性 實現管道符 |  命名管道 命名管道特性 程式碼實現 管道讀寫規則 作業系統中ipc的相關命令 共享記憶體(重點) 生命週期: 程式碼實現 程式碼實現獲

    Windows程式訊息機制:訊息與程序通訊

    自定義訊息與程序間通訊 視窗程式可以接收自定義的訊息型別,前提是通訊的程序聲明瞭這種訊息型別,宣告的方法很簡單,WM_USER加一個值就可以了,一般加的值從0x400開始,其他的值已經被系統使用了。 實現一個完整的自定義訊息需要進行以下步驟:

    程序通訊管道--pipefifo使用

    匿名管道pipe 函式原型: #include <unistd.h> int pipe(int fildes[2]); 引數說明 fildes是我們傳入的陣列,也是一個傳出引數。fildes[0]是讀端,fildes[1]是寫端。 返回值 成功呼叫返回0。 失敗呼叫返回-1且

    程序通訊——共享記憶體Shared Memory簡易原理建立_獲得函式

    共享記憶體是System V版本的最後一個程序間通訊方式。共享記憶體,顧名思義就是允許兩個不相關的程序訪問同一個邏輯記憶體,共享記憶體是兩個正在執行的程序之間共享和傳遞資料的一種非常有效的方式。不同程序之間共享的記憶體通常為同一段實體記憶體。程序可以將同一段實體記憶體連線到他們自己的地址空間中,所有

    34-程序通訊——FIFO命名管道

    1. 何為命名管道   在前面的學習中我們知道管道(pipe)只能用於“有血緣關係”的程序間。    它們之間最大的區別就是FIFO提供一個路徑名與之關聯,在檔案系統中有一個索引塊,以檔案路徑的形式存在(在磁碟中沒有資料塊,所有資料都存放在核心),而這個檔案路

    Linux高階程式設計5————程序通訊1無名管道

    程序通訊簡介: IPC(程序間通訊),前面我們學習了程序控制,瞭解程序間隔離的,各自有獨立的虛擬記憶體空間無法直接訪問對方的地址空間、程序排程和均衡則讓程序互不干擾地使用處理器資源。但有時需要多個程序相

    Linux環境程序通訊 管道有名管道(轉)

    管道是Linux支援的最初Unix IPC形式之一,具有以下特點:管道是半雙工的,資料只能向一個方向流動;需要雙方通訊時,需要建立起兩個管道;只能用於父子程序或者兄弟程序之間(具有親緣關係的程序);單獨構成一種獨立的檔案系統:管道對於管道兩端的程序而言,就是一個檔案,但它不是普通的檔案,它不屬於某種檔案系統,

    程序通訊IPC——管道通訊

    IPC(Inter-Process Communication)程序間通訊,提供了各種程序間通訊的方法。在Linux C程式設計中有幾種方法 (1) 半雙工Unix管道 (2) FIFOs(命

    QT之程序程序通訊IPC

    程序是作業系統的基礎之一。一個程序可以認為是一個正在執行的程式。我們可以把程序當做計算機執行時的一個基礎單位。關於程序的討論已經超出了本章的範疇,現在我們假定你是瞭解這個概念的。 在 Qt 中,我們使用QProcess來表示一個程序。這個類可以允許我們的應用程式開啟一個新的外部程式

    程序通訊PIPE呼叫

    看過了高階的popen呼叫之後,我們來了解一下底層的pipe函式。popen函式用過啟動一個shell來解釋請求的命令。而pipe不需要啟動shell來解釋。 #include<unistd.h> int pipe(int file_descriptor[2]

    Linux 程序通訊方式 pipe函式

    Linux 程序間通訊方式有以下幾種: 1-》管道(pipe)和有名管道(fifo). 2-》訊息佇列 3-》共享記憶體 4-》訊號量 5-》訊號(signal) 6-》套接字(sicket) 在這裡我們看一下第一種====管道(pipe)。有名管道(fifo)見其它文章。