进程间通信___命名管道(FIFO)

命名管道(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



上一篇:BZOJ 3143 游走(高斯消元)


下一篇:3月31日学习笔记(CSS基础)