linux IPC的FIFO

FIFO命名管道原型:

#include <sys/stat.h>

int mkfifo(const char *path, mode_t mode);
int mkfifoat(int fd, const char *path, mode_t mode);

FIFO是一种文件类型,通过stat获取st_mode类型。

mkfifo的一个例子:

 1 #include <sys/types.h>
 2 #include <sys/stat.h>
 3 #include <fcntl.h>
 4 #include <stdio.h>
 5 #include <unistd.h>
 6 
 7 int main(void)
 8 {
 9     char buf[80];
10     char s[] = "Hello!\n";
11     int fd;
12     pid_t pid;
13 
14     unlink("my_fifo");
15     mkfifo("my_fifo", 0777);
16 
17     if((pid = fork()) < 0) {
18         printf("fork error");
19         return -1;
20     } else if(pid == 0)    {                 /* child */
21         fd = open("my_fifo", O_RDONLY);
22 
23         read(fd, buf, sizeof(buf));
24         
25         printf("The message from pipe is:%s\n", buf);
26 
27     } else {                              /* parent */
28         fd = open("my_fifo", O_WRONLY);
29 
30         write(fd, s, sizeof(s));
31     }
32 
33     return 0;
34 }

说明:

mkfifoat与mkfifo相似,像之前其他*at系列函数一样,有3种情形:

(1)   如果path参数指定了绝对路径名,则fd被忽略,此时mkfifoat和mkfifo一样。

(2)   如果path参数指定了相对路径名,则fd参数是一个打开目录的有效文件描述符,路径名和目录有关。

(3)   如果path参数指定了相对路径名,并且fd参数指定了AT_FDCWD,则路径名以当前目录开始,mkfifoat和mkfifo类似。

当我们使用mkfifo或者mkfifoat函数创建FIFO时,要用open打开,确是,正常的I/O函数(如close、read、write、unlink)都需要FIFO。当open一个FIFO时,非阻塞标志(O_NONBLOCK)会产生如下影响:

(1)   没有指定O_NONBLOCK时,只读open要阻塞到某个其他进程为写而打开这个FIFO为止。类似地,只写open要阻塞到某个其他进程为读而打开这个FIFO为止。

(2)   如果指定了P_NONBLOCK,则只读open立即返回。但是,如果没有进程为读而打开这个FIFO,那么只写open将返回-1,并将errno设置为ENXIO。

一个给定的FIFO有多个写进程是很常见的,这就意味着,如果不希望多个进程所写的数据交叉,则必须考虑原子写操作。和管道一样,常量PIPE_BUF说明了可被原子地写到FIFO的最大数据量。

posted @ 2017-12-18 21:42  习惯就好233  阅读(218)  评论(0编辑  收藏  举报