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 }
时间: 2024-08-08 13:50:39

Linux-进程间通信(二): FIFO的相关文章

linux 进程间通信 之fifo

上一篇博客已经介绍了一种进程间通信的方式,但是那只是针对于有血缘关系的进程,即父子进程间的通信,那对于没有血缘关系的进程,那要怎么通信呢?  这就要创建一个有名管道,来解决无血缘关系的进程通信, fifo: [email protected]:~$ mkfifo xwp [email protected]:~$ ls -l myfifo prw-rw-r-- 1 book book 0 Feb 6 2016 myfifo mkfifo 既有命令也有函数 #include <sys/types.h

Linux进程间通信(二) - 消息队列

消息队列 消息队列是Linux IPC中很常用的一种通信方式,它通常用来在不同进程间发送特定格式的消息数据. 消息队列和之前讨论过的管道和FIFO有很大的区别,主要有以下两点(管道请查阅我的另一篇文章:http://www.cnblogs.com/linuxbug/p/4863724.html): Ø  一个进程向消息队列写入消息之前,并不需要某个进程在该队列上等待该消息的到达,而管道和FIFO是相反的,进程向其中写消息时,管道和FIFO必须已经打开来读,否则写进程就会阻塞(默认情况下). Ø 

Linux环境编程之IPC进程间通信(二):管道

管道作为最古老的进程间通信方法,它有以下几个特点: 1.在所有的UNIX实现中都存在. 2.没有名字,因此只能由有亲缘关系的进程使用. 3.它由函数pipe创建,read和write函数访问,但只提供单路(单向)数据流. <span style="font-size:14px;">#include <unistd.h> int pipe(int fd[2]); 返回:若成功则为0,若出错则为-1</span> 经由参数fd返回两个文件描述符:fd[0

嵌入式 Linux进程间通信(十二)——多线程同步

嵌入式 Linux进程间通信(十二)--多线程同步 多线程编程中有三种线程同步机制:互斥锁.信号量.条件量.本文将使用生产者消费者问题编程实践三种线程同步方式. 生产者.消费者问题:生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费.消费者线程从缓冲区中获得物品,然后释放缓冲区.当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区.当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来. 一.互斥锁

Linux 系统开发5 进程间通信 pipe() fifo() mmap()

[本文谢绝转载,原文来自http://990487026.blog.51cto.com] Linux 系统开发5 进程间通信 pipe() fifo() mmap() pipe()管道通信介绍 pipe()父子进程通信案例 pipe()使用管道有一些限制 pipe()管道缓存区大小 pipe() 读端非阻塞管道 fifo()管道文件 fifo()写端/读端程序 管道文件在磁盘上的大小是0 mmap()将文件映射到内存 mmap()写端/读端程序 mmap()传输结构体数据,删除临时文件 pipe

嵌入式 Linux进程间通信(二)——exec族函数

嵌入式 Linux进程间通信(二)--exec族函数 exec函数族的作用是根据指定的文件名找到可执行文件,并用它来取代调用进程的内容,换句话说,就是在调用进程内部执行一个可执行文件.这里的可执行文件既可以是二进制文件,也可以是任何Linux下可执行的脚本文件. exec族函数包含如下函数: #include <unistd.h> extern char **environ; int execl(const char *path, const char *arg, ...); int exec

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

 无名管道(pipe) 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信: 定义函数: int pipe(int filedes[2]) filedes[0]为管道里的读取端 filedes[1]则为管道的写入端. 实现机制: 管道是由内核管理的一个缓冲区,相当于我们放入内存中的一个纸条.管道的一端连接一个进程的输出.这个进程会向管道中放入信息.管道的另一端连接一个进程的输入,这个进程取出被放入管道的信息.一个缓

Linux进程间通信之管道(pipe)、命名管道(FIFO)与信号(Signal)

整理自网络 Unix IPC包括:管道(pipe).命名管道(FIFO)与信号(Signal) 管道(pipe) 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信: 实现机制: 管道是由内核管理的一个缓冲区,相当于我们放入内存中的一个纸条.管道的一端连接一个进程的输出.这个进程会向管道中放入信息.管道的另一端连接一个进程的输入,这个进程取出被放入管道的信息.一个缓冲区不需要很大,它被设计成为环形的数据结构,以便管

Linux进程间通信总结

Linux进程间通信总结 1. 管道 管道是Linux支持的最初Unix IPC形式之一,具有以下特点: (1)管道是半双工的,数据只能向一个方向流动:需要双方通信时,需要建立起两个管道: (2)只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程): (3)单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中. (4)数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出

Linux进程间通信 -- 使用命名管道

在前一篇文章—— Linux进程间通信 -- 使用匿名管道 中,我们看到了如何使用匿名管道来在进程之间传递数据,同时也看到了这个方式的一个缺陷,就是这些进程都由一个共同的祖先进程启动,这给我们在不相关的的进程之间交换数据带来了不方便.这里将会介绍进程的另一种通信方式——命名管道,来解决不相关进程间的通信问题. 一.什么是命名管道 命名管道也被称为FIFO文件,它是一种特殊类型的文件,它在文件系统中以文件名的形式存在,但是它的行为却和之前所讲的没有名字的管道(匿名管道)类似. 由于Linux中所有