天天看點

程序間通信(IPC)2 ------ 有名管道

      管道的一個不足之處是沒有名字,是以隻能在具有親緣關系的程序之間通信。而“有名管道”與此不同,它提供了一個路徑名與之關聯,作為一個裝置檔案存在,即使無親緣關系的程序之間,隻要能通路該路徑,也可以通過FIFO進行通信。FIFO總是按照先進先出的原則工作,第一個被寫入的資料将首先從管道中讀出。

      函數原型:

#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *path,mode_t mode);
           

      path為建立有名管道的路徑名;mode為建立有名管道的模式,指明其存取權限。函數調用成功傳回0,失敗傳回-1。

      使用一個存在的有名管道之前,需要用open()将其打開。因為有名管道是一個存在于硬碟上的檔案,而管道是存在于記憶體中的特殊檔案。

      以下程式示範有名管道在無親緣關系的程序之間如何通信。

//procwriter.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

#define FIFO_NAME	"myfifo"
#define BUF_SIZE	1024

int main(void)
{
	int     fd;
	char	buf[BUF_SIZE] = "Hello procwrite, I come from process named procread!";

	umask(0);
	//指明建立一個有名管道且存取權限為0666,即建立者、與建立者同組的使用者、其他使用者對該有名管道的通路權限都是可讀可寫
	if (mkfifo (FIFO_NAME, S_IFIFO | 0666) == -1)		
	{
		perror ("mkfifo error!");
		exit (1);
	}

	if((fd = open (FIFO_NAME, O_WRONLY) ) == -1)/*以寫方式打開FIFO*/
	{
		perror ("fopen error!");
		exit (1);
	}
	write (fd, buf, strlen(buf)+1); /*向FIFO寫資料*/

	close (fd);
	exit (0);
}
           

procreader.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>

#define FIFO_NAME  	"myfifo"
#define BUF_SIZE    	1024

int main(void)
{
        int     fd;
        char    buf[BUF_SIZE];

        umask (0);
        fd = open(FIFO_NAME, O_RDONLY);
        read (fd, buf, BUF_SIZE);
        printf ("Read content: %s\n", buf);
        close (fd);
        exit (0);
}
           

      首先運作procwrite(運作後處于阻塞狀态),打開另一個終端運作程式procread。結果如下:

程式間通信(IPC)2 ------ 有名管道
程式間通信(IPC)2 ------ 有名管道

繼續閱讀