Linux进程间通信二--有名管道FIFO
来源:互联网 发布:js 正则匹配数字 编辑:程序博客网 时间:2024/05/16 01:39
一、有名管道概念
上一节对无名管道做了阐述,无名管道只能用在两个有亲缘关系的进程直接。而有名管道FIFO可以用在任意两进程之间,它依赖于文件系统,是一个存在的特殊文件。
有名管道和普通文件一样具有磁盘存放路径。文件权限和其他属性。但是,有名管道和普通文件又有区别,有名管道并没有在磁盘正存放真正的信息,它存储的通信信息在内存中,两进程结束后自动丢失,拥有一个磁盘路径仅仅是一个接口,其目的是使进程间信息的编程更简单统一。通信的两个进程结束后,有名管道的文件路径本身仍然存在,这是和无名管道不一样的地方。有名管道的特性可以总结为一下几点:
1.可以用于同一台PC下任意两进程通信;
2.无法seek,要保持先入先出(FIFO)原则;
3.有名管道通信是单项的;
4.有名管道本身不会随通信双方的结束而消失,但有名管道中的内容会随着通信双方结束消失。
二、创建有名管道
mkfifo()
函数用来创建有名管道,其函数声明如下:
// come from /usr/include/sys/stat.h/*Create a new FIFO named PATH, with permission bits MODE*/int mkfifo(const char* path, __mode_t mode);
第一个参数path为要创建的管道文件名;
第二个参数mode为生成文件的模式。
mkfifo()
会根据参数建立特殊的有名管道文件,该文件必须不存在。mkfifo()
创建的FIFO文件其他进程都可以用读写一般文件的方式存取。当使用open()函数打开FIFO文件是,O_NONBLOCK会有影响。
三、读写有名管道
有名管道的实质和无名管道一样是一段内核管理的内存空间。但在通过write和read系统调用来执行读写操作前,需要调用open()函数来打开该文件。另外,操作无名无名管道的阻塞位置为open()位置,而不是有名管道的读写位置。
1.打开有名管道
如果希望以写的方式打开管道,则需要另一个进程以读的方式打开管道,否则一直阻塞。反过来如果以读的方式打开管道,则需要另一进程以写的方式打开管道,否则一直阻塞。即,如果以某种方式打开有名管道,则系统将阻塞进程,直到有另一个进程(包括自己)以另一种方式打开该管道后才会继续执行。显然,一个进程以可读可写方式打开管道,当前进程充当了读和写两个身份,进程不会阻塞。
2.两进程已经完成打开管道操作,阻塞读操作按一下方式执行:
a.如果管道中没有数据,读操作默认阻塞;
b.如果管道中有数据,但小于期望读取数据量,读出所有数据返回;
c.如果管道中有数据,但大于期望读取数据量,读出期望大小数据返回。
3.两进程已经完成打开管道操作,阻塞写操作按一下方式执行:
a.如果管道中没有空间,写操作阻塞;
b.如果管道中有空间,但小于期望写入数据量,写满空间后阻塞;
c.如果管道中有空间,但大于期望写入数据量,写入数据后返回。
4.两进程已经完成打开管道操作,中途其中一个进程退出:
a.未退出一端如果是写操作,将返回SIGPIPE信号;
b.未退出一端如果是阻塞读操作,读操作将不再阻塞,直接返回0。
四、示例
下面给出在父子进程间使用FIFO通信的示例,在非情缘关系的进程间原理是一样的:
#include <stdio.h> #include <unistd.h>#include <signal.h>#include <sys/types.h>#include <fcntl.h>#define FIFO_PATH "./fifo"void handler(int sig){ printf("sig=%d\n", sig);}int main() { signal(SIGPIPE, handler); unlink(FIFO_PATH); // 删除原来的管道 mkfifo(FIFO_PATH, 0644); // 创建管道 pid_t pid = fork(); if (pid < 0) { perror("fork error"); return -1; } if (0 == pid) { // 子进程 int fd; fd = open(FIFO_PATH, O_WRONLY); write(fd, "hello world!", 12); sleep(1); close(fd); } else { // 父进程 int fd; char buf[128] = {0}; fd = open(FIFO_PATH, O_RDONLY); int ret = read(fd, buf, sizeof(buf)); printf("ret=%d buf=%s\n", ret, buf); close(fd); } return 0;}
运行结果如下所示:
- Linux进程间通信二--有名管道FIFO
- Linux--进程间通信(管道及有名管道FIFO)
- Linux--进程间通信(管道及有名管道FIFO)
- Linux--进程间通信(管道及有名管道FIFO)
- linux进程通信----FIFO(有名管道)
- linux进程间通信-有名管道(FIFO)
- linux进程间通信-有名管道(FIFO)
- linux编程---进程间通信---FIFO---有名管道
- Linux进程间通信——有名管道 FIFO 详解
- Linux环境进程间通信(二):有名管道(FIFO)
- 嵌入式 Linux环境进程间通信(二):有名管道(FIFO)
- 进程间通信______有名管道(FIFO)
- 进程间的通信----有名管道fifo
- 进程通信-有名管道FIFO
- Linux--进程间通信(管道及有名管道FIFO)(转)
- Linux--进程间通信(管道及有名管道FIFO)(转)
- Linux进程间通信(一)之无名管道(PIPE)和有名管道(FIFO)
- linux进程通信--有名管道(FIFO)(含实例代码)
- B
- MySql的flush用法
- Python正则表达式(高级教程)
- itchat研究笔记
- hammer.js 一个多点触摸手势库
- Linux进程间通信二--有名管道FIFO
- [c#]ini文件读写
- jbpm框架定义事件
- webstorm 相关nodejs设置
- 多态 虚函数
- 修改服务器端上传大小限制
- POJ 3246:Game 题解 (凸包)
- 浅析Java反射
- Python CGI编程(高级教程)