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的主要内容,如果未能解决你的问题,请参考以下文章