Linux-进程间通信: FIFO

Posted Alex

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux-进程间通信: FIFO相关的知识,希望对你有一定的参考价值。

1. FIFO:

FIFO也被成为命名管道,可以用于任意进程间通信,而普通无名管道只能用于有共同祖先的进行直接通信;

命名管道也是半双工的,open管道的时候不要以读写方式打开,这种操作是未定义的;

 

2. FIFO创建:

#include <sys/stat.h>

int mkfifo(const char *pathname, mode_t mode);

ret = 成功返回0,失败返回-1

FIFO是一种文件类型,mode参数与open函数中的mode参数相同,并且一般文件的操作函数(close, read, write, unlink等)都以用于FIFO;

 

3. 非阻塞标志(O_NONBLOCK):

(1) 阻塞模式:只读open要阻塞到某个进程为写而打开此FIFO,只写open要阻塞到某个进程为读而打开此FIFO;

(2) 非阻塞模式:只读立即返回,如果没有进程为读而打开FIFO,则只写open返回-1,erron=ENXIO;

 

4. 一端关闭:

(1) 若读一个已经关闭写端的FIFO,则读取完数据后,会读到文件结束符,read返回0;

(2) 若写一个已经关闭读端的FIFO,则产生SIGPIPE;

 

5. 用途:

(1) FIFO由shell命令使用以便将数据从一条管道传送到另一条,而无需创建临时文件;

(2) FIFO用于客户进程和服务器进程进行数据传递;

 

6. 测试代码:

fifo_writer.c -- 向fifo中写入字串

 1 #include <unistd.h>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <string.h>
 5 #include <limits.h>
 6 #include <sys/stat.h>
 7 #include <sys/types.h>
 8 #include <fcntl.h>
 9 
10 #define FIFO_NAME "/var/tmp/fifo_test"
11 #define BUF_LEN PIPE_BUF
12 
13 
14 int main(int argc, char *argv[])
15 {
16     int pipeid = -1;
17     int fifoid = -1;
18 
19     char buffer[BUF_LEN] = { 0 };
20 
21     if (access(FIFO_NAME, F_OK) < 0){
22         fifoid = mkfifo(FIFO_NAME, 0777);
23         if (fifoid < 0){
24             perror("mkfifo error\n");
25             return -1;
26         }
27     }
28 
29     pipeid = open(FIFO_NAME, O_WRONLY);
30     if (pipeid < 0){
31         perror("open pipeid error\n");
32         return -1;
33     }
34 
35     int read_bytes = read(STDIN_FILENO, buffer, BUF_LEN);
36     if (read_bytes < 0){
37         perror("read error\n");
38         close(pipeid);
39         return -1;
40     }
41 
42     const char * buff_send = buffer;
43     int no_write_bytes = read_bytes;
44     while (no_write_bytes > 0){
45         int n = write(pipeid, buff_send, no_write_bytes);
46         if (n < 0){
47             perror("write error\n");
48             close(pipeid);
49             return -1;
50         }
51 
52         no_write_bytes -= n;
53         buff_send += n;
54     }
55 
56     close(pipeid);
57 
58     return 0;
59 }

 

fifo_reader.c --  从fifo中读出字串

 1 #include <unistd.h>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <string.h>
 5 #include <limits.h>
 6 #include <sys/stat.h>
 7 #include <sys/types.h>
 8 #include <fcntl.h>
 9 
10 #define FIFO_NAME "/var/tmp/fifo_test"
11 #define BUF_LEN PIPE_BUF
12 
13 
14 int main(int argc, char *argv[])
15 {
16     int pipeid = -1;
17 
18     char buffer[BUF_LEN] = { 0 };
19 
20     pipeid = open(FIFO_NAME, O_RDONLY);
21 
22     int n = read(pipeid, buffer, BUF_LEN - 1);
23     if (n < 0){
24         perror("read error\n");
25         close(pipeid);
26         return -1;
27     }
28 
29     write(STDOUT_FILENO, buffer, n);
30 
31     close(pipeid);
32 
33     return 0;
34 }

 

以上是关于Linux-进程间通信: FIFO的主要内容,如果未能解决你的问题,请参考以下文章

Linux系统编程——进程间通信:命名管道(FIFO)

linux 进程间通信 之fifo

[Linux进程间通信]FIFO

简述Linux进程间通信之命名管道FIFO

linux 进程间通信 命名管道FIFO的原理与使用

Linux 进程间通信之管道(pipe),(fifo)