管道文件分为存在内存的无名管道和存在磁盘的有名管道,无名管道只能用于具有亲缘关系的进程之间,这就大大限制了管道的使用。而有名管道可以解决这个问题,他可以实现任意两个进程之间的通信。
有名管道的创建可以使用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;
}
为了更好的观察效果,需要把这两个程序分别放在两个终端里面运行,这里应该首先启动读程序,然后在写程序中输入内容,该内容会立即在读取的终端里面显示。