1. 程式人生 > >程序通訊之命名管道(FIFO)

程序通訊之命名管道(FIFO)

匿名管道只能於有血緣關係的程序,那麼倆個沒有任何關係的程序怎麼通訊,這就出現了命名管道來克服這一問題。命名管道是一個裝置檔案,只要訪問該路徑,就能通過這個共享資源來互相通訊。FIFO是按照先進先出的原則工作的,第一個被寫入的資料第一個先被讀出。FIFO可被用於複製序列管道命令之間的輸出流,於是也就不需要寫資料到中間磁碟檔案中(類似於使用管道以避免中間的磁碟檔案);

命名管道的建立:

在shell下互動的建立命名管道

mkfifo命令建立管道:


mknod命令建立管道:

mknod [OPTION]... NAME TYPE [MAJOR MINOR]     

option 有用的就是 -m 了     

name   自定義    

 type   有 b (塊裝置),c(字元裝置), p(管道)     


在程式中使用系統函式建立命名管道

int mknod(const *filename, mode_t mode | S_IFIFO,(dev_t)0); int mkfifo(const char *filename,mode_t mode) mknod是比較老的函式,經常使用的是mkfifo(更加簡單和規範)這裡著重理解mkfifo這個函式。 filename為建立命名管道的全路徑名,比如在當前路徑下建立一個名為mypipe的管道,filename的值為"./mypipe" 建立管道:
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
int main()
{
	//umask(0);
	if(mkfifo("./mypipe",S_IFIFO | 0666) < 0){
		perror("mkfifo\n");
		return -1;
	}
	return 0;
}
命名管道的使用: 與匿名管道的使用方法基本是相同的,不過使用命名管道時需要先呼叫open()開啟;呼叫open時需要注意的是,呼叫open()開啟命名管道的程序可能會被阻塞,但如果同時用讀寫方式(O_RDWR)開啟,則不一定會導致阻塞;如果以只讀方式(O_RDONLY)/(O_WRONLY)開啟,則呼叫open()函式的程序會將被阻塞直到有寫/讀方式開啟管道; 接下來會建立兩個程序來驗證沒有血緣關係的兩個程序通訊; 程序1:
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
int main() //client read
{
	int fd = open("./mypipe",O_RDONLY);
	if(fd < 0){
		perror("open\n");
		return -2;
	}
	char buf[100];
	memset(buf,'\0',sizeof(buf));
	while(1)
	{
		buf[0] = 0;
		int ret = read(fd,buf,sizeof(buf));
		if(ret <0){
			perror("write error\n");
		}
		
		printf("sever:%s\n",buf);
	}
	close(fd);
	return 0;
}

程序2:
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
int main() //sever write
{
	umask(0);
	if(mkfifo("./mypipe",S_IFIFO | 0666) < 0){
		perror("mkfifo\n");
		return -1;
	}
	int fd = open("./mypipe",O_WRONLY);
	if(fd < 0){
		perror("open\n");
		return -2;
	}
	char buf[100];
	memset(buf,'\0',sizeof(buf));
	while(1)
	{
		buf[0] = 0;
		scanf("%s",buf);
		if(write(fd,buf,sizeof(buf))<0){
			perror("write error\n");
			return -3;
		}
		//sleep(1);
	}
	close(fd);
	return 0;
}
兩程序通訊:


命名管道是一個可見的檔案,因此,它可以用於任何兩個程序間進行通訊。