定名管道文件的使用

命名管道文件的使用

管道文件分为存在内存的无名管道和存在磁盘的有名管道,无名管道只能用于具有亲缘关系的进程之间,这就大大限制了管道的使用。而有名管道可以解决这个问题,他可以实现任意两个进程之间的通信。

有名管道的创建可以使用mkfifo函数,函数的使用类似于open函数的使用,可以指定管道的路径和打开的模式。

示例代码:

/*fifo_read.c*/

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO "/tmp/myfifo"	/*定义管道文件的目录文件名*/
#define STOP "stop"		/*定义读取操作终止命令*/

int main(void)
{
	/*读缓冲区*/
	char buffer_read[100];
	int fd;
	int bytes_read;

	/*调用mkfifo函数创建命名管道文件*/
	if( (mkfifo(FIFO,O_CREAT | O_EXCL)) < 0 && (errno != EEXIST) )
	{
		printf("Cannot create fifo file!\n\a");
		exit(1);
	}
	printf("Preparing for reading bytes.....\n");
	/*清0缓冲区数据*/
	memset(buffer_read,0,sizeof(buffer_read));
	/*以非阻塞的方式打开管道文件*/
	fd = open(FIFO,O_RDONLY | O_NONBLOCK);
	if( fd == -1 )
	{
		perror("Open:");
		exit(1);
	}
	/*无限循环,每隔一秒读取管道文件,直到STOP命令到来*/
	while(1)
	{
		memset(buffer_read,0,sizeof(buffer_read));
		if( (bytes_read=read(fd,buffer_read,100)) == -1 )
		{
			if( errno == EAGAIN )
				printf("No data!\n\a");
		}
		if( strcmp(STOP,buffer_read) ==0 )
			break;
		printf("Read %s from FIFO!\n",buffer_read);
		sleep(1);
	}
	/*关闭并删除管道文件*/
	unlink(FIFO);

	return 0;
}

这是一个创建并读取管道的程序,下面是写入的程序:

/*fifo_write.c*/

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO "/tmp/myfifo"	/*定义管道文件的目录和文件名*/

int main(int argc,char *argv[])
{
	int fd;
	char buffer_write[100];
	int bytes_write;
	
	if( argc == 1)
	{
		printf("Usage:%s string\n",argv[0]);
		exit(1);
	}
	/*以非阻塞的方式打开管道文件*/
	fd = open(FIFO,O_WRONLY | O_NONBLOCK);
	if( fd == -1 )
	{
		printf("Open error:no reading process!\n");
		exit(1);
	}
	strcpy(buffer_write,argv[1]);
	if( (bytes_write=write(fd,buffer_write,100)) == -1 )
	{
		if( errno == EAGAIN )
		{
			printf("The FIFO has not been read!\n\a");
			exit(1);
		}
	}
	else
		printf("Write %s to the FIFO!\n",buffer_write);

	return 0;
}

为了更好的观察效果,需要把这两个程序分别放在两个终端里面运行,这里应该首先启动读程序,然后在写程序中输入内容,该内容会立即在读取的终端里面显示。