天天看點

Linux系統程序間通信:命名管道(FIFO) ,用mkfifo來建立

FIFO簡介: 

FIFO,即命名管道, 也是Linux系統的一種程序間通信方式,不同于匿名管道,命名管道可以進行“非父/子關系”程序間通信,而且以檔案節點的形式在。使用mkfiifo可以建立這個檔案節點檔案。

First In First Out的縮寫,意為先進先出,正好是指令管道的特點。

 命名管道是一個特殊的檔案節點:

要使用FIFO,先建立fifo檔案,讀端通過read來從fifo讀取(類似于檔案讀取);寫端通過read來從fifo讀取(類似于檔案寫入)。

 下面是一個命名管道檔案:

fifo1.lnk

fifo1.lnk就是建立的管道,可見,字尾是lnk檔案。命名管道以一種特殊的檔案形式存在,在提供管道功能的同時,也具有了普通檔案的優點(可以同時被多個程序夾享)。

mkfifo函數聲明:

#include <sys/types.h>

#include <sys/stat.h>

int mkfifo( const char* pathname, mode_t mode );

功能:建立命名管道,即“在檔案系統中建立一個檔案,該檔案用于提供FIFO功能”。

參數:

第一個參數(pathname)是将要在檔案系統中建立的一個專用檔案;

第二個參數(mode)用來規定FIFO的讀寫權限。

傳回值:

如果調用成功的話,傳回值為0;

如果調用失敗傳回值為-1。

 FIFO使用舉例:

下面我們以一個執行個體來說明如何使用mkfifo函數建一個FIFO,以及進行FIFO的讀寫。

實作兩個c檔案,分别進行讀和寫,在讀端進行FIFO檔案節點的建立,并讀取資料;在寫端把資料寫入FIFO檔案節點。

read_fifo.c(讀端):

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

/* 讀 */
int main()
{
	int fd;
	int len;
	char buf[1024];

	if(mkfifo("fifo1", 0666) < 0 && errno!=EEXIST) // 建立FIFO管道
		perror("Create FIFO Failed");

	if((fd = open("fifo1", O_RDONLY)) < 0)  // 以讀打開FIFO
	{
		perror("Open FIFO Failed");
		exit(1);
	}
	
	while((len = read(fd, buf, 1024)) > 0) // 讀取FIFO管道
		printf("Read message: %s", buf);

	close(fd);  // 關閉FIFO檔案
	return 0;
}
           

 讀端調用mkfifo和read。fifo1就是建立的管道。

write_fifo.c(寫端):

#include<stdio.h>
#include<stdlib.h>   // exit
#include<fcntl.h>    // O_WRONLY
#include<sys/stat.h>
#include<time.h>     // time

int main()
{
	int fd;
	int n, i;
	char buf[1024];
	time_t tp;

	printf("I am %d process.\n", getpid()); // 說明程序ID
	
	if((fd = open("fifo1", O_WRONLY)) < 0) // 以寫打開一個FIFO 
	{
		perror("Open FIFO Failed");
		exit(1);
	}

	for(i=0; i<10; ++i)
	{
		time(&tp);  // 取系統目前時間
		n=sprintf(buf,"Process %d's time is %s",getpid(),ctime(&tp));
		printf("Send message: %s", buf); // 列印
		if(write(fd, buf, n+1) < 0)  // 寫入到FIFO中
		{
			perror("Write FIFO Failed");
			close(fd);
			exit(1);
		}
		sleep(1);  // 休眠1秒
	}

	close(fd);  // 關閉FIFO檔案
	return 0;
}
           

寫端調用open和write。 

編譯和運作:

分别用gcc編譯,得到兩個可執行程式:一個read ,一個write,分别用于讀寫。

read的運作結果:

Read message: Process 3372's time is Thu July 15 07:35:08 2010

Read message: Process 3372's time is Thu July 15 07:35:09 2010

Read message: Process 3372's time is Thu July 15 07:35:10 2010

Read message: Process 3372's time is Thu July 15 07:35:11 2010

Read message: Process 3372's time is Thu July 15 07:35:12 2010

write的運作結果:

I am 3372 process.

Send message: Process 3372's time is Thu July 15 07:35:08 2010

Send message: Process 3372's time is Thu July 15 07:35:09 2010

Send message: Process 3372's time is Thu July 15 07:35:10 2010

Send message: Process 3372's time is Thu July 15 07:35:11 2010

Send message: Process 3372's time is Thu July 15 07:35:12 2010

可見,在read中,建立管道,并且讀取資料; 在write中,向管道寫入資料。