程序間的通訊方式_管道(有名管道)
阿新 • • 發佈:2019-02-04
當從一個程序連線資料流到另一個程序時,我們使用屬於管道(pipe)。我們通常是把一個程序的輸出通過管道連線到另一個程序的輸入。
(管道是在記憶體上開闢出一塊空間,不被任何其他程序所佔用的)管道包括全雙工通訊和半雙工通訊。
管道原理:
管道操作: 有名管道:應用於任意兩個程序之間資料的單向傳遞 建立:命令方式(mkfifo)、函式方式(mkfifo) 開啟:open 寫資料:write 讀資料:read 關閉:close 有名管道是在檔案目錄樹中有一個檔案標識(管道檔案),實際不佔用磁碟空間,資料快取在記憶體中。 與通過 pipe 呼叫建立管道不同,FIFO 是以命名檔案的形式存在, 而不是開啟的檔案描述符,所以在對它進行讀寫操作之前必須先開啟它。FIFO 也用 open 和 close 函式開啟和關閉,這與我們的對檔案的操作一樣,但它多了一些其他功能,對 FIFO 來說, 傳遞給 open 呼叫的是 FIFO 的路徑名, 而不是一個正常的檔案。 阻塞執行函式:函式呼叫後並不會立即返回,需要等待某些條件的發生才會返回,open 操作管道檔案時,阻塞執行的函式。 如果一個程序以只寫方式開啟一個管道檔案,open 會阻塞執行,直到有一個程序以讀的方式開啟這個管道檔案,open 才會返回,程序才會接著執行。 如果一個程序以只讀方式開啟一個管道檔案,open 會阻塞執行,直到有一個程序以寫的方式開啟這個管道檔案,open 才會返回,程序才會接著執行。 read 函式也會阻塞執行, 直到寫端寫入資料或所有寫端關閉時返回。 read 讀取資料並且會將記憶體上的已讀資料清空。 練習:A程序負責迴圈接受使用者輸入的資料,以“end”為結束標誌,B程序負責統計使用者輸入的單詞的個數,顯示到介面上。 首先利用 mkfifo FIFO 命令建立管道檔案“FIFO”,如圖所示:
A程序程式碼如下:
管道操作: 有名管道:應用於任意兩個程序之間資料的單向傳遞 建立:命令方式(mkfifo)、函式方式(mkfifo) 開啟:open 寫資料:write 讀資料:read 關閉:close 有名管道是在檔案目錄樹中有一個檔案標識(管道檔案),實際不佔用磁碟空間,資料快取在記憶體中。 與通過 pipe 呼叫建立管道不同,FIFO 是以命名檔案的形式存在, 而不是開啟的檔案描述符,所以在對它進行讀寫操作之前必須先開啟它。FIFO 也用 open 和 close 函式開啟和關閉,這與我們的對檔案的操作一樣,但它多了一些其他功能,對 FIFO 來說, 傳遞給 open 呼叫的是 FIFO 的路徑名, 而不是一個正常的檔案。 阻塞執行函式:函式呼叫後並不會立即返回,需要等待某些條件的發生才會返回,open 操作管道檔案時,阻塞執行的函式。 如果一個程序以只寫方式開啟一個管道檔案,open 會阻塞執行,直到有一個程序以讀的方式開啟這個管道檔案,open 才會返回,程序才會接著執行。 如果一個程序以只讀方式開啟一個管道檔案,open 會阻塞執行,直到有一個程序以寫的方式開啟這個管道檔案,open 才會返回,程序才會接著執行。 read 函式也會阻塞執行, 直到寫端寫入資料或所有寫端關閉時返回。 read 讀取資料並且會將記憶體上的已讀資料清空。 練習:A程序負責迴圈接受使用者輸入的資料,以“end”為結束標誌,B程序負責統計使用者輸入的單詞的個數,顯示到介面上。 首先利用 mkfifo FIFO 命令建立管道檔案“FIFO”,如圖所示:
B程序程式碼如下:#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <assert.h> #include <fcntl.h> int main() { int fd = open("FIFO", O_WRONLY); assert(fd != -1); if (fd == -1) { exit(0); } char buffer[128] = {0}; printf("Please input:"); fgets(buffer, 128, stdin); while (strncmp(buffer,"end",3) != 0) { write(fd, buffer, strlen(buffer)-1); memset(buffer, 0, 128); fgets(buffer, 128, stdin); } close(fd); return 0; }
測試執行結果如圖所示:#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <assert.h> #include <fcntl.h> int main() { int fd = open("FIFO", O_RDONLY); assert(fd != -1); if (fd == -1) { exit(0); } char buffer[128] = {0}; int count = 0; while (read(fd,buffer,127) > 0) { printf("%s\n", buffer); count++; } printf("count: %d\n",count); close(fd); return 0; }