Linux/Unix下管道通信仅限与父子进程和兄弟进程之间,另外一种是FIFO(First In First Out,先进先出) 也叫有名管道是可以令两个没有关系的进程进行通信的,其实编程时把FIFO就当成是一种特殊的文件来处理就行了,先进先出的一端读数据一端写数据想必是很清楚,还有就是它是不能lseek函数的。
一、创建FIFO文件的过程就类似创建文件的creat函数:
int mkfifo(const char *pathname, mode_t mode);
/ Returns: 0 if OK, -1 on error /
创建文件后,可以像打开普通文件一样使用open()函数打开FIFO文件,之后就可以使用read,write等函数来对这个文件进行操作了。
二、关于打开文件时候的 O_NONBLOCK (非阻塞)选项:
在正常情况下(默认没有设置O_NONBLOCK选项),以只读模式打开FIFO,也就是读进程中打开一个FIFO文件时,如果没有其他进程向FIFO写数据,那么读进程在执行open函数中就开始阻塞,直到有其他进程打开了FIFO写数据时,读进程中的open函数才返回。
在设置了O_NONBLOCK选项的情况,读进程在打开FIFO文件时立刻从open函数中返回并且可以开始从FIFO中读数据的操作。但是如果在读进程还没有准备好读数据时一个写进程以只写模式打开一个FIFO文件时,open函数返回-1,并且errno置为ENXIO。
编程的时候就是先让读进程准备好从FIFO读取数据,然后写进程再朝FIFO写数据就行了。
fifo_read.c:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
int main(int argc, char *argv[])
{
int fd;
int n;
char buf[BUFFSIZE];
if (mkfifo(FIFO,FILE_MODE)<0)
{
if (errno==EEXIST)
perror("FIFO 文件已经存在");
else
perror("创建FIFO文件错误");
}
if((fd=open(FIFO,O_RDONLY|O_NONBLOCK,0))==-1)
{
perror("打开FIFO失败");
unlink(FIFO);
exit(1);
}
while (1)
{
if ((n=read(fd,buf,BUFFSIZE))>0)
printf("%d Bytes Read From FIFO: %s n",n,buf);
else if (n==0)
printf("当前FIFO是空的.n");
else
perror("从FIFO读取失败n");
sleep(1);
}
if (close(fd)==-1)
{
perror("关闭FIFO失败");
unlink(FIFO);
exit(1);
}
unlink(FIFO);
exit(0);
}
fifo_write.c:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
int main(int argc, char *argv[])
{
int fd;
size_t n;
char buf[BUFFSIZE] = "This is a IPC Message";
if ((fd = open(FIFO,O_WRONLY|O_NONBLOCK,0))==-1)
{
err_sys("打开FIFO失败");
unlink(FIFO);
exit(1);
}
while (1)
{
if ((n=write(fd,buf,BUFFSIZE))>0)
printf("%d Bytes Write To FIFO : %s n",n,buf);
else
err_sys("不能写FIFOn");
sleep(1);
}
if (close(fd)==-1)
{
err_sys("关闭FIFO失败");
unlink(FIFO);
exit(1);
}
unlink(FIFO);
exit(0);
}