Linux进程间通信-FIFO命名管道
Linux进程间通信-FIFO命名管道
1、概述
管道因为没有名称,所以只用于进程间的亲缘通信。为了克服这一缺点,提出了命名管道(FIFO),又称命名管道、FIFO文件。
FIFO不同于无名管道,它提供与之关联的路径名,该路径名以FIFO文件的形式存在于文件系统中。这样,即使进程与FIFO的创建进程没有亲属关系,只要能够访问路径,就可以通过FIFO相互通信。不相关的过程也可以通过FIFO交换数据。
FIFO 在文件系统中作为一个特殊的文件而存在。虽然FIFO文件存放在文件系统中,但是FIFO 中的内容却存放在内存中。当使用 FIFO 的进程退出后,FIFO 文件将继续保存在文件系统中以便以后使用。
2、相关函数
一旦创建了一个FIFO,就可用open打开它,一般的文件访问函数(close、read、write等)都可用于FIFO。
FIFO在使用的过程中常用到如下函数
| 函数 | 释意 |
|---|---|
| mkfifo | 创建管道 |
| open | 打开管道 |
| read | 读管道 |
| write | 写管道 |
| unlink | 关闭管道 |
| unlink | 删除管道 |
上述函数中除了mkfifo函数需要注意一下,其他的函数全是标准的IO操作接口,这里不做解释。使用fifo之前需要使用mkfifo创建一个管道,同时会在指定位置创建一个用于描述管道的文件。
#include <sys/types.h>
#include <sys/stat.h>
/*
pathname:FIFO文件名
mode:属性(见文件操作章节)
返回值:若成功则返回0,否则返回-1,错误原因存于errno中。
错误代码:
EACCESS 参数pathname所指定的目录路径无可执行的权限
EEXIST 参数pathname所指定的文件已存在。
ENAMETOOLONG 参数pathname的路径名称太长。
ENOENT 参数pathname包含的目录不存在
ENOSPC 文件系统的剩余空间不足
ENOTDIR 参数pathname路径中的目录存在但却非真正的目录。
EROFS 参数pathname指定的文件存在于只读文件系统内。
*/
int mkfifo(const char * pathname, mode_tmode)
打开管道时,默认是阻塞模式,写管道时如果没有其他进程读管道写管道就会阻塞住。同理,读管道操作也是如此,如果没有进程写管道,读管道就会被阻塞住。打开管道时以O_NONBLOCK的标志打开fifo文件,程序会直接返回,不管fifo的对端是什么状态。
3、例程
写入测试程序,先判断FIFO文件是否存在,如果文件不存在则调用mkfifo创建一个FIFO通道。以OPEN打开FIFO通道,调用fgets获取控制台输入的内容,使用write方法将数据写入到FIFO通道。
#include <errno.h>
#include <stdlib.h> //for exit
#include <stdio.h> //for printf
#include <unistd.h> //for close
#include <sys/stat.h> //for mkfifo
#include <fcntl.h> //for open
#define FIFO_NUM1 "/tmp/fifotest"
#define MAX_BUFFER_SIZE 100
int main(int argc, char * argv[])
{/* 判断有名管道是否已存在,若尚未创建,则以相应的权限创建 */if (access(FIFO_NUM1, F_OK) == -1){if ((mkfifo(FIFO_NUM1, 0777) < 0) && (errno != EEXIST)){printf("Failed to create fifo file\n");exit(1);}}/* 以只写阻塞方式打开FIFO管道 */int fd = open(FIFO_NUM1, O_WRONLY);if (fd == -1){printf("Failed to open fifo\n");exit(1);}while(1){char buff[MAX_BUFFER_SIZE] = {0};fgets(buff,sizeof(buff),stdin);/* 向管道中写入字符串 */if (write(fd, buff, MAX_BUFFER_SIZE) > 0){printf("Write '%s' to FIFO\n", buff);}}close(fd);exit(0);
}
读取测试程序,同样先判断FIFO文件是否存在,不存在则调用mkfifo创建一个FIFO通道。使用read循环读取FIFO的内容并打印出来。
#include <errno.h>
#include <stdlib.h> //for exit
#include <stdio.h> //for printf
#include <unistd.h> //for close
#include <sys/stat.h> //for mkfifo
#include <fcntl.h> //for open
#define FIFO_NUM1 "/tmp/fifotest"
#define MAX_BUFFER_SIZE 100
int main(void)
{/* 判断有名管道是否已存在,若尚未创建,则以相应的权限创建 */if (access(FIFO_NUM1, F_OK) == -1){if ((mkfifo(FIFO_NUM1, 0777) < 0) && (errno != EEXIST)){printf("Failed to create fifo file\n");exit(1);}}/* 以只读阻塞方式打开有名管道 */int fd = open(FIFO_NUM1, O_RDONLY);if (fd == -1){printf("Failed to open fifo\n");exit(1);}while (1){char buff[MAX_BUFFER_SIZE] = {0};if (read(fd, buff, MAX_BUFFER_SIZE) > 0){printf("Read '%s' from fifo\n", buff);}}close(fd);exit(0);
}
使用gcc分别编译文件,然后直接调用就可以运行了。可以看到运行结果与预期一致。
$ gcc ./write.c -o write
$ ./write
11
Write '11
' to FIFO
222
Write '222
' to FIFO
333
Write '333
' to FIFO
444
Write '444
' to FIFO
$ gcc ./read.c -o read
$ ./read
Read '11
' from fifo
Read '222
' from fifo
Read '333
' from fifo
Read '444
' from fifo
4、题外话
FIFO管道在创建时,会锁定文件的权限。我上面写的例程,创建FIFO时写入的是0777的权限,实际生成的FIFO文件却是755的权限。也就是说,FIFO文件只有创建者有权限读写,其他成员只能读取,不能执行写入的动作。
$ ls -l /tmp/fifotest
prwxr-xr-x 1 zac zac 0 Nov 18 16:40 /tmp/fifotest
如果有两个应用之间通过FIFO通信,但两个应用属于不同的用户。这时候读取进程按照上面所说的例程方式,先启动创建了FIFO文件。那么等写入进程运行起来后,将无法进行FIFO管道的写入操作。
这时候读取进程需要做出一些小修改。可以每隔一段时间查询一下FIFO文件的状态,等待写入进程成功创建FIFO文件。
xxxxxx/* 判断有名管道是否已存在,若尚未创建,则等待片刻*/while(access(FIFO_NUM1, F_OK) == -1){usleep(200*1000);}xxxxxx
5、总结
- 要创建和打开管道,只需调用pipe。创建和打开一个FIFO,在调用mkfifo后还需要使用open;
- 管道在所有进程最终关闭后自动消失,只有通过调用unlink才能从文件系统中删除FIFO名称。
- 创建FIFO文件时会锁定文件的写入权限,只有创建者才有资格写入
相关文章:
Linux进程间通信-FIFO命名管道
Linux进程间通信-FIFO命名管道 1、概述 管道因为没有名称,所以只用于进程间的亲缘通信。为了克服这一缺点,提出了命名管道(FIFO),又称命名管道、FIFO文件。 FIFO不同于无名管道,它提供与之关联的路径名,该路径名以FIF…...
【Kafka】记录一次基于connect-mirror-maker做的Kafka集群迁移完整过程
文章目录背景环境工具选型实操MM1MM2以MM2集群运行以Standalone模式运行验证附录MM2配置表其他背景 一个测试环境的kafka集群,Topic有360,Partition有2000,部署在虚拟机上,由于多方面原因,要求迁移至k8s容器内&#x…...
实现VOC数据集与COCO数据集格式转换
实现VOC数据集与COCO数据集格式转换2、将voc数据集的xml转化为coco数据集的json格式2、COCO格式的json文件转化为VOC格式的xml文件3、将 txt 文件转换为 Pascal VOC 的 XML 格式<annotation><folder>文件夹目录</folder><filename>图片名.jpg</file…...
常用的密码算法有哪些?
我们将密码算法分为两大类。 对称密码(密钥密码)——算法只有一个密钥。如果多个参与者都知道该密钥,该密钥 也称为共享密钥。非对称密码(公钥密码)——参与者对密钥的可见性是非对称的。例如,一些参与者仅…...
SNS (Simple Notification Service)简介
SNS (Simple Notification Service) 是一种完全托管的发布/订阅消息收发和移动通知服务,用于协调向订阅终端节点和客户端的消息分发。 和SQS (Simple Queue Service)一样,SNS也可以轻松分离和扩展微服务,分布式系统和无服务应用程序…...
JVM初步理解浅析
一、JVM的位置 JVM的位置 JVM在操作系统的上一层,是运行在操作系统上的。JRE是运行环境,而JVM是包含在JRE中 二、JVM体系结构 垃圾回收主要在方法区和堆,所以”JVM调优“大部分也是发生在方法区和堆中 可以说调优就是发生在堆中…...
【巨人的肩膀】MySQL面试总结(一)
💪 目录💪1、什么是ER图2、数据库范式了解吗3、超键、候选键、主键、外键分别是什么?4、为什么不推荐使用外键与级联5、什么是存储过程6、drop、delete与truncate区别7、数据库设计通常分为那几步8、什么是关系型数据库9、什么是SQL10、MySQL…...
【数据结构之树】——什么是树,树的特点,树的相关概念和表示方法以及在实际的应用。
文章目录一、1.树是什么?2.树的特点二、树的相关概念三、树的表示方法1.常规方法表示树2.使用左孩子右兄弟表示法3. 使用顺序表来存储父亲节点的下标三、树在实际的应用总结一、1.树是什么? 树是一种非线性的数据结构,它是由n(n&…...
JavaScript语法
文章目录一、JavaScript是什么?JavaScript引入方式二、基础语法书写语法输出语句变量数据类型运算符流程控制语句数组函数JS变量作用域对象一、JavaScript是什么? JavaScript:是一门跨平台的脚本语言,用来控制网页行为࿰…...
【BIOS/UEFI】HII 基本框架及概述
HII(Human Interface Infrastructure )定义了一套管理用户输入的基础框架。HII数据库主要提供用户安装、卸载以及使用各种字符串、字体和图片等资源的接口。 HID Devices 是用户输入设备,如键盘、串口和网络;Display Devices 是输…...
sprintf(...)溢出边界导致程序崩溃的问题
文章目录小结问题及解决参考小结 使用sprintf(...)进行格式化是一种标准的做法,但是这样做是有一个极大的风险,由于sprintf(...)不进行边界检查,这样会有写操作溢出边界的风险,并导致程序崩溃。本文进行了简单写操作溢出边界的测…...
公式推导+dfs简版
写在前面的话:心可以冷,但手不能停 第一题:C. Flexible String 题目大意:给一个aaa字符串和bbb字符串和数字kkk,首先设置一个计数器cntcntcnt,其中可以对aaa字符串做以下操作:替换aaa中的一个字母xxx&#…...
论文笔记 | 标准误聚类问题
关于标准误的选择,如是否选择稳健性标准误、是否采取聚类标准误。之前一直是困惑的,惯用的做法是类似主题的文献做法。所以这一次,借计量经济学课程之故,较深入学习了标准误的选择问题。 在开始之前推荐一个知乎博主。他阅读了很…...
银行管理系统--课后程序(Python程序开发案例教程-黑马程序员编著-第7章-课后作业)
实例1:银行管理系统 从早期的钱庄到现如今的银行,金融行业在不断地变革;随着科技的发展、计算机的普及,计算机技术在金融行业得到了广泛的应用。银行管理系统是一个集开户、查询、取款、存款、转账、锁定、解锁、退出等一系列的功…...
【18】组合逻辑 - VL18 实现3-8译码器①
VL18 实现3-8译码器① 1 题目 【这题我的思路非常绝境】奈斯 !! 看真值表的思路:Yi所在列【0仅一个其余全1】,故【以0为对象求解】 观察发现:E3 E2_n E1_n = 100 时 是 译码的使能信号 ; 并且E3 E2_n E1_n为其他值时,都不使能译码 然后就很简单,没有仿真就成功了 2 代…...
2020蓝桥杯真题最长递增 C语言/C++
题目描述 在数列a_1 ,a_2,⋯,a_n 中,如果a_i <a_i1 <a_i2<⋯<a_j,则称 a_i至 a_j为一段递增序列,长度为 j−i1。 定一个数列,请问数列中最长的递增序列有多长。 输入描述 输入的第一行包含一个整数 n。 第二行包含…...
华为OD机试题 - 寻找连续区间(JavaScript)| 机考必刷
更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:寻找连续区间题目输入输出示例一输入输出说明示例二输入输出Cod…...
一次疲惫的调试--累了及时透气
原创 射频清茶 深山小老虎 2023-03-11 14:32发表于广东 收录于合集 #射频调试3个 #网分4个 #Wi-Fi 2个 进来透透气 道不尽红尘舍恋 诉不完人间恩怨 世世代代都是缘 喝着相同的水 留着相同的血 这条路漫漫又长远 红花当然配绿叶 这一辈子谁来陪 渺渺茫茫来又回 往日情景再…...
综合练习7 摄氏度转华氏温度(“\t“的使用,循环语句)
综合练习7 摄氏度转华氏温度 使用do…while循环,在控制台输入摄氏温度与华氏温度的对照表。 对照表从摄氏温度-30℃到50℃,每行间隔10℃,运行如下: 摄氏温度:-30℃ 华氏温度:-22.0℉ 摄氏温度:…...
AWS数据库总结
RDS – 联机事务处理OLTP(Online Transaction Processing),包括: SQL ServerOracleMySQL ServerPostgreSQLAuroraMariaDB非关系数据库DynamoDB数据仓库RedShift – 联机分析处理OLAP(Online Analytics Processing&…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...
LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)
在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
加密通信 + 行为分析:运营商行业安全防御体系重构
在数字经济蓬勃发展的时代,运营商作为信息通信网络的核心枢纽,承载着海量用户数据与关键业务传输,其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级,传统安全防护体系逐渐暴露出局限性&a…...
