Linux进程间通信之命名管道
文章目录
0.背景知识
学习命名管道
需要了解管道
的基本原理,这部分内容在上一篇文章 Linux进程间通信之匿名管道(点击直达) 有所提及,建议先学习命名管道
。
1.命名管道 fifo
有血缘关系
的进程之间通信可以使用匿名管道 pipe
,无血缘关系
的两个进程如何进行数据传递呢?
命名管道 fifo
,使用 一个磁盘上的 fifo 文件,标识内核中的一条管道通路,该 fifo 文件数据部分大小0
。进程 A 和进程 B 可以使用打开文件的方式打开 myfifo
文件,进行 write and read
,实际上读写的还是 myfifo 标识的内核中的缓冲区
。
2.mkfifo 函数介绍
2.1 函数原型
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
2.2 函数功能
mkfifo
函数用于创建一个 命名管道
文件。mkfifo
函数具有一个同名的Linux 命令,同样用于创建 命名管道
。此处我使用 mkfifo
命令创建了一个名为 myfifo
的命名管道文件
,我们查看创建命名管道文件
发现其并不占用硬盘空间
,其文件类型
是p 管道类型
。
2.3 形参解释
- 形参
const char* pathname
:用于指定生成的命名管道
文件路径 - 形参
mode_t mode
:用于指定生成命名管道
文件的权限
2.4 返回值解释
- 成功返回:
0
- 失败返回:
-1
,并且设置errno
3.案例程序之两个无血缘关系进程数据传递
/**
* 写进程 fifo_w.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
/**
* 打印错误信息
*/
void sys_error(const char* err, int exitno){
perror(err);
exit(exitno);
}
int main()
{
int fd = open("myfifo",O_WRONLY);
if(-1 == fd){
int ret = mkfifo("myfifo", 0777);
if(-1 == ret)
sys_error("mkfifo",-1);
fd = open("myfifo", O_WRONLY);
}
char buf[1024] = "Later better than never.\n";
int writed = write(fd, buf, strlen(buf));
if(-1 == writed)
sys_error("write",1);
close(fd);
return 0;
}
/**
* 写进程 fifo_r.c
*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
/**
* 打印错误信息
*/
void sys_error(const char* err, int exitno){
perror(err);
exit(exitno);
}
int main()
{
int fd = open("myfifo",O_RDONLY);
char buf[1024];
int readed = read(fd, buf, sizeof(buf));
if(-1 == readed)
sys_error("read",1);
int ret = write(STDOUT_FILENO, buf, strlen(buf));
if(-1 == ret)
sys_error("write",1);
close(fd);
return 0;
}
程序运行结果