命名管道(FIFO)
基本概念
命名管道和一般的管道基本相同,但也有一些显著的不同:
命名管道是在文件系统中作为一个特殊的设备文件而存在的。
不同祖先的进程之间可以通过管道共享数据。
当共享管道的进程执行完所有的I/O操作以后,命名管道将继续保存在文件系统中以便以后使用。
管道只能由相关进程使用,它们共同的祖先进程创建了管道。但是,通过FIFO,不相关的进程也能交换数据。
命名管道创建和操作::
#include
#include
int mkfifo(const char *pathname, mode_t mode);
返回:若成功则为0,若出错则为-1
一旦已经用mkfifo创建了一个FIFO,就可用open打开它。确实,一般的文件I/O函数(close、read、write、unlink等)都可用于FIFO。
当打开一个FIFO时,非阻塞标志(O_NONBLOCK)产生下列影响:
(1) 在一般情况中(没有说明O_NONBLOCK),只读打开要阻塞到某个其他进程为写打开此FIFO。类似,为写而打开一个FIFO要阻塞到某个其他进程为读而打开它。
(2) 如果指定了O_NONBLOCK,则只读打开立即返回,但是,如果没有进程已经为读而打开一个FIFO,那么只写打开将出错返回,其errno是ENXIO。
类似于管道,若写一个尚无进程为读而打开的FIFO,则产生信号SIGPIPE。若某个FIFO的最后一个写进程关闭了该FIFO,则将为该FIFO的读进程产生一个文件结束标志。
FIFO相关出错信息:
EACCES (无存取权限)
EEXIST (指定文件不存在)
ENAMETOOLONG (路径名太长)
ENOENT (包含的目录不存在)
ENOSPC (文件系统剩余空间不足)
ENOTDIR (文件枯井无效)
EROFS (指定的文件存在于只读文件系统中)
fifo_read.c文件内容如下:
#include
#include
#include
#include
#define FIFO “/tmp/myfifo”
main(int argc, char **argv)
{
char buf_r[100];
int fd;
int nread;
if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST))
printf(“cannot create fifoserver\n”);
printf(“Preparing for reading bytes…\n”);
memset(buf_r, 0, sizeof(buf_r);
fd=open(FIFO, O_RDONLY|O_NONBLOCK,0);
if(fd==-1)
{
perror(“open”);
exit(1);
}
while(1)
{
memset(buf_r,0,sizeof(buf_r));
if((nread=read(fd,buf_r,100))==-1){
if(errno==EAGAIN)
printf(“no data yet\n”);
}
printf(“read %s from FIFO\n”,buf_r);
sleep(1);
}
pause();
unlink(FIFO);
}
fifo_write.c文件内容如下:
#include
#include
#include
#include
#include
#include
#define FIFO_SERVER “/tmp/myfifo”
main(int argc, char **argv)
{
int fd;
char w_buf[100];
nt nread;
if(fd==-1)
if(error==ENXIO)
printf(“open error;no reading process\n”
fd=open(FIFO_SERVER, O_WRONLY|O_NONBLOCK,0);
if(argc==1)
print(“please send something\n”)
strcpy(w_buf, argv[1]);
if((nwrite==write(fd,w_buf,100))==-1)
{
if(errno==EAGAIN)
printf(“The FIFO has not been read yet. Please try later\n”);
}
else
{
printf(“write %s to the FIFO\n”, w_buf);
}
gcc –o fifo_read fifo_read.c
gcc –o fifo_write fifo_write.c
运行结果:
读管道:
./fifo_read
Preparing for reading bytes…
read from FIFO
read from FIFO
read from FIFO
read from FIFO
read from FIFO
read from FIFO
写管道:
./fifo_write ccccccccccc
write ccccccccccc to the FIFO
读管道:
read from FIFO
read from FIFO
read from FIFO
read from FIFO
read ccccccccccc from FIFO
read from FIFO
read from FIFO
read from FIFO