1. 程式人生 > >程序間的通訊方式_管道(有名管道)

程序間的通訊方式_管道(有名管道)

當從一個程序連線資料流到另一個程序時,我們使用屬於管道(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程序程式碼如下:
#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;
}
      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_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;
}
測試執行結果如圖所示: