Linux进程间通信(IPC)之二——命名管道(FIFO)
来源:互联网 发布:代账用什么软件 编辑:程序博客网 时间:2024/06/08 07:04
1 命名管道(FIFO)
经过前文《Linux进程间通信(IPC)之一——管道》介绍管道,但是管道应用的一个重大缺陷就是没有名字,因此只能用于亲缘进程之间的通信。后来从管道为基础提出命名管道(named pipe,FIFO)的概念,该限制得到了克服。FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间),因此,通过FIFO不相关的进程也能交换数据。值得注意的是,FIFO严格遵循先进先出(first in first out),对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾。它们不支持诸如lseek()等文件定位操作。
2 命名管道的创建
#include <sys/types.h>#include <sys/stat.h>int mkfifo(const char *pathname, mode_t mode);
3 命名管道操作
FIFO在文件系统中表现为一个文件,大部分的系统文件调用都可以用在FIFO上面,比如:read,open,write,close,unlink,stat等函数。但是seek等函数不能对FIFO调用。
可以调用open打开FIFO,请注意以下方面:
1、当以阻塞(未指定O_NONBLOCK)方式只读打开FIFO的时候,则将会被阻塞,知道有其他进程以写方式打开该FIFO。
2、类似的,当以阻塞(未指定O_NONBLOCK)方式只写打开FIFO的时候,则将会被阻塞,知道有其他进程以读方式打开该FIFO。
3、当以非阻塞方式(指定O_NONBLOCK)方式只读打开FIFO的时候,则立即返回-1,其errno是ENXIO。
4 应用实例
本例为一个client-server模式,服务器端将会创建一个闻名fifo文件(本例中为“/tmp/server”),并读取该fifo文件。客户端则打开该fifo文件,并把其请求写入该FIFO文件。服务器端读取该命令并执行之。
服务器端的代码为:
#include <stdio.h>#include <errno.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>struct fifo_cmd{pid_t child_pid;char cmd[100];};int main(void){int fd;struct fifo_cmd cmd;int err;int n;if((err = mkfifo("/tmp/server", 0777)) < 0){if(errno != EEXIST){perror("mkfido fail: ");exit(-1);}}if((fd = open("/tmp/server", O_RDONLY)) < 0){perror("open fail: ");exit(-1);}while(1){if((n = read(fd, &cmd, sizeof(cmd))) < 0){perror("read fail: ");exit(-1);}if(n > 0){printf("command from %d: %s\n", cmd.child_pid, cmd.cmd);}sleep(1);}}
请把这个代码编译成server。
客户端代码如下:
#include <stdio.h>#include <errno.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <fcntl.h>#include <string.h>struct fifo_cmd{pid_t pid;char cmd[100];};int main(int argc, char* argv[]){int fd;struct fifo_cmd cmd;if((fd = open("/tmp/server", O_WRONLY)) < 0){perror("open fail: ");exit(-1);}cmd.pid = getpid();while(1){printf("%%: ");fgets(cmd.cmd, sizeof(cmd.cmd), stdin);cmd.cmd[strlen(cmd.cmd) - 1] = 0;if(write(fd, &cmd, sizeof(cmd)) < 0){perror("write fail: ");exit(-1);}}}
请把客户端代码编译成client。
测试时我们可以启动多个client,我们将会看到client发生命令将会在服务器端执行之。
5 总结
与管道相比,FIFO最大的特点就是其在文件系统中有fifo文件存在,这样就可以做到进程间通信。
- Linux进程间通信(IPC)之二——命名管道(FIFO)
- Linux进程间通信(IPC)之二——命名管道(FIFO)
- Linux进程间通信(IPC)之二——命名管道(FIFO)
- Linux进程间通信(IPC)之二——命名管道(FIFO)
- Linux进程间通信(IPC)编程实践(二) FIFO命名管道
- 命名管道(FIFO) Linux进程进程间的通信之命名管道(FIFO)
- 进程间的通信(二)命名管道fifo
- 进程间通信--命名管道(fifo)
- Linux下进程间通信机制:FIFO(命名管道)
- Linux下进程间通信机制:FIFO(命名管道)
- 进程间的通信之命名管道(FIFO)
- Linux系统编程——进程间通信:命名管道(FIFO)
- Linux系统编程——进程间通信:命名管道(FIFO)
- Linux系统编程——进程间通信:命名管道(FIFO)
- 【Linux】进程间通信(IPC)之匿名管道和命名管道以及测试用例
- Linux(八):进程通信IPC(二)之命名管道
- Linux环境进程间通信(一)——管道(pipe)和命名管道(fifo)
- Linux环境进程间通信(一)——管道(pipe)和命名管道(fifo)
- JDK1.6在LINUX下的安装配置
- Linux进程间通信(IPC)之一——管道
- 代码的加载地址与运行地址
- SQL语句注释的妙用
- 程序员必知8大排序3大查找(三)
- Linux进程间通信(IPC)之二——命名管道(FIFO)
- 往MySQL中存储图片 ---java项目中
- 修改Windows Server2003/SQL Server2005的密码后速达软件的配置
- 使用NLC来辅助网络相关程序的测试
- 互联网项目管理要点
- 无法将“Invoke-SqlCmd”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。
- C++跨平台应用编译方法详解
- 关于spring annotation扫描目录的定义
- JTS Geometry Operations(二)