无名管道 / 有名管道(FIFO)
根据上节所讲就可以了解到:管道其实就是实现进程间通讯IPC中的一种类型方法
基本概念(无名管道)
管道是一种最基本的IPC机制,通常指无名管道,也是UNIX系统IPC最古老的形式。管道只能作用于有血缘关系的进程之间,完成数据传递。调用pipe系统函数即可创建一个管道。有如下特质:
- 其本质是一个伪文件(实为内核缓冲区),可以使用普通的read,write等函数进行读写
- 由两个文件描述符引用,一个表示读端,一个表示写端
- 规定数据从管道的写端流入管道,从读端流出
管道的原理
管道实为内核使用环形队列机制,借助内核缓冲区(4k)实现。
管道的局限性
- 数据一旦被读走,便不在管道中存在,不可反复读取
- 由于管道采用半双工通信方式。因此,数据只能在一个方向上流动
所谓半双工,其实在讲串口的时候就提到过,也就是同一时间要么只能写要么只能读,不能同时写和读。 对于进程通讯就是:父进程写的时候子进程只能读;子进程写的时候父进程只能读。
- 只能在有公共祖先的进程间使用管道
( 常见的通信方式有,单工通信、半双工通信、全双工通信 )
pipe函数(无名管道)
当成功调用pipe函数时,会创建两个文件描述符,fd[0] -> 读(r),fd[1]-> 写(w),之后如果想要向管道写数据就往fd[1]里面写,如果想从管道读数据就从fd[0]里面读!
如果要关闭管道,只需要关闭这两个文件描述符就可以了。
需要添加的库
#include <unistd.h>
函数原型
int pipe(int pipefd[2]);
函数参数
- pipefd[2]:表示一个包含两个文件描述符的数组,也就是上面提到分别代表读和写的 fd[0] 和 fd[1]
- 返回值:若成功返回0,失败则返回-1
实操演示
创建一个名为'IPC"的文件夹,关于各种IPC的学习代码都放在这个文件夹下:
注意,由于fork函数会拷贝一份一样的程序给子进程,所以管道的创建应该在fork之前,这样父子进程就都有了fd[0]和fd[1],并且由于管道指向内核,所以父子进程的fd[0]和fd[1]是相同的。
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>int main()
{int fd[2];pid_t fork_return;char *writebuf = "mjmmjmmm";char readbuf[1024] = {0};if(pipe(fd) == -1){printf("pipe error\n");}fork_return = fork();if(fork_return > 0){//fatherclose(fd[0]);//ssize_t write(int fd, const void *buf, size_t count);write(fd[1],writebuf,strlen(writebuf));wait(NULL);}else if(fork_return == -1){//errorprintf("fork error\n");}else{//sonclose(fd[1]);//ssize_t read(int fd, void *buf, size_t count);read(fd[0],&readbuf,1024);printf("read from pipe:%s\n",readbuf);exit(1);}return 0;
}
实现效果
基本概念(有名管道)
FIFO,也称为命名管道,它是一种文件类型。
有名管道的特点
- FIFO可以在无关的进程之间交换数据,与无名管道不同
- FIFO有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中
mkfifo函数(有名管道)
需要添加的库
#include <sys/stat.h>
函数原型
int mkfifo(const char *pathname, mode_t mode);
函数参数
- pathname:文件路径
- mode:mode 参数与
open
函数中的 mode 相同。一旦创建了一个 FIFO,就可以用一般的文件I/O函数操作它
关于open函数中的mode:
其中较为常用的是:
- S_IRWXU:对主用户来说可读,可写,可执行
- S_IRUSR:对主用户来说可读
- S_IWUSR:对主用户来说可写
- S_IXUSR:对主用户来说可执行
详见:Linux 系统编程 开篇/ 文件的打开/创建_mjmmm的博客-CSDN博客
- 返回值:成功返回0,出错返回-1
既然可以用一般文件的I/O函数操作它,就意味可以使用open来打开,而open中的第二个参数flag中有一个选项是“
O_NONBLOCK
”,这是非阻塞标志:
若没有指定
O_NONBLOCK
(默认),只读 open 要阻塞到某个其他进程为写而打开此 FIFO。类似的,只写 open 要阻塞到某个其他进程为读而打开它。若指定了
O_NONBLOCK
,则只读 open 立即返回。而只写 open 将出错返回 -1 如果没有进程已经为读而打开该 FIFO,其errno置ENXIO。参考:进程间通信(一)管道的pipe函数 FIFO的mkfifo函数_mkfifo 多进程_点灯小哥的博客-CSDN博客
实操演示
FIFO的通讯方式类似于在进程中使用文件来传输数据,只不过FIFO类型文件同时具有管道的特性。在数据读出时,FIFO管道中同时清除数据,并且“先进先出”
fifo1.c:(只读open FIFO,并不设“O_NONBLOCK”)
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>int main()
{if(mkfifo("./fifo",S_IRWXU) == -1 && errno != EEXIST) //如果创建失败 且 没有已存在的FIFO{printf("mkfifo failed\n");perror("why");}int fd = open("./fifo",O_RDONLY); //only readprintf("open success\n");return 0;
}
实现效果1:
可见,由于没有设置O_NONBLOCK,且没有进程只写打开FIFO,所以只读打开FIFO会一直阻塞
fifo2.c:(只读open FIFO,并设置“O_NONBLOCK”)
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>int main()
{if(mkfifo("./fifo",S_IRWXU) == -1 && errno != EEXIST){printf("mkfifo failed\n");perror("why");}int fd = open("./fifo",O_RDONLY|O_NONBLOCK); //only readprintf("open success\n");return 0;
}
实现效果2:
可见,由于加上了O_NONBLOCK,虽然没有进程只写打开FIFO,但是只读打开不会阻塞而是立刻返回,并执行了printf
fifo3.c & fifo4.c:(创建两个进程,fifo3一直写,fifo4一直读)
fifio3.c:(一直写)
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>int main()
{char *str = "mjmmmmjjm";int fd = open("./fifo",O_WRONLY); //only writeprintf("open success\n");while(1){write(fd,str,strlen(str));sleep(1);}close(fd);return 0;
}
fifo4.c:(一直读)
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>int main()
{char buf[30] = {0};int nread = 0;if(mkfifo("./fifo",S_IRWXU) == -1 && errno != EEXIST){printf("mkfifo failed\n");perror("why");}int fd = open("./fifo",O_RDONLY); //only readprintf("read open success\n");while(1){read(fd,&buf,30);printf("read %d byte from fifo,context: %s\n",nread,buf);}close(fd);return 0;
}
实现效果3:
先编译并运行fifo4.c:
可见没有进程只写打开FIFO,所以一直阻塞
然后再新的窗口编译并运行fifo3.c:
此时有进程只写打开FIFO并每隔一秒向其中写入数据
此时再观察fifo4.c的输出:
此时只读FIFO不再阻塞,并每隔一秒读到只写FIFO写入的数据!
上述例子可以扩展成 客户进程—服务器进程 通信的实例,负责写的fifo3.c的作用类似于客户端,可以打开多个客户端向一个服务器发送请求信息,负责读的fifo4.c类似于服务器,它适时监控着FIFO的读端,当有数据时,读出并进行处理,但是有一个关键的问题是,每一个客户端必须预先知道服务器提供的FIFO接口,下图显示了这种安排:
相关文章:

无名管道 / 有名管道(FIFO)
根据上节所讲就可以了解到:管道其实就是实现进程间通讯IPC中的一种类型方法 基本概念(无名管道) 管道是一种最基本的IPC机制,通常指无名管道,也是UNIX系统IPC最古老的形式。管道只能作用于有血缘关系的进程之间&…...

Three.js纹理贴图
目录 Three.js入门 Three.js光源 Three.js阴影 Three.js纹理贴图 纹理是一种图像或图像数据,用于为物体的材质提供颜色、纹理、法线、位移等信息,从而实现更加逼真的渲染结果。 纹理可以应用于Three.js中的材质类型,如MeshBasicMaterial…...

1+X Web前端开发职业技能等级证书建设方案
一 、系统概述 1X Web前端开发技术是计算机类专业重要的核心课程,课程所包含的教学内容多,实践性强,并且相关技术更新快。传统的课堂讲授模式以教师为中心,学生被动式接收,难以调动学生学习的积极性和主动性。混合式教…...

Rx.NET in Action 第二章学习笔记
2 Hello, Rx 本章节涵盖的内容: 不使用Rx的工作方式向项目中添加Rx创建你的第一个Rx应用程序 Rx 的目标是协调和统筹来自社交网络、传感器、用户界面事件等不同来源的基于事件的异步计算。例如,建筑物周围的监控摄像头和移动传感器会在有人靠近建筑物时触发…...
【软件工程 | 模块耦合】什么是模块耦合及分类
概念 耦合(coupling)是对两个模块之间联接程度的一种度量。模块间的依赖程度越大,则其耦合程度也就越大; 反之,模块间的依赖程度越小,则其耦合程度也就越小。 很显然,为了使软件具有较好的可维护性和可修改性…...

OCT介绍和分类
前言:研究方向和OCT有关,为了方便以后回顾,所以整理了OCT相关的一些内容。 OCT介绍和分类 OCT介绍分类时域OCT频域OCT扫频OCT谱域OCT OCT介绍 名称:OCT、光学相干层析成像术、Optical Coherence Tomography。 概念:O…...

07-2_Qt 5.9 C++开发指南_二进制文件读写(stm和dat格式)
文章目录 1. 实例功能概述2. Qt预定义编码文件的读写2.1 保存为stm文件2.2 stm文件格式2.3 读取stm文件 3. 标准编码文件的读写3.1 保存为dat文件3.2 dat文件格式3.3 读取dat文件 4. 框架及源码4.1 可视化UI设计4.2 mainwindow.cpp 1. 实例功能概述 除了文本文件之外ÿ…...

SpringBoot复习:(41)配置文件中配置的server开头的属性是怎么配置到Servlet容器中起作用的?
ServletWebServerFactoryAutoConfiguration类: 可以看到其中使用了EnableConfigurationProperties导入了ServerProperties 而ServerProperties通过使用ConfigurationProperties注解导入了配置文件中已server开头的那些配置项。 可以看到ServletWebServerFactory定…...
深入解读网络协议:原理与重要概念
目录 TCP/IP协议 IP地址 子网掩码 DNS 网关 网络端口 TCP/IP协议 TCP/IP是互联网通信的基础协议。它由两个部分组成:TCP负责数据的可靠传输,确保数据按序到达目标;IP负责寻址和路由,确保数据在网络中正确传递。TCP/IP协议簇…...
O型圈不同类型的应用指南
O型圈因其优异的密封性能而广泛应用于各个行业和应用。它们简单、经济高效且密封可靠,下面我们了解一下适合每种应用的特定类型的O型圈。 1、汽车行业 在汽车行业中,O型圈在密封发动机部件和防止机油或冷却剂泄漏方面发挥着至关重要的作用。常见应用包…...

Mysql 搭建MHA高可用架构,实现自动failover,完成主从切换
目录 自动failover MHA: MHA 服务 项目:搭建Mysql主从复制、MHA高可用架构 实验项目IP地址配置: MHA下载地址 项目步骤: 一、修改主机名 二、编写一键安装mha node脚本和一键安装mha mangaer脚本,并执行安装…...
Python:列表、元组、集合、字典,数据类型之间的 5 个差异
Python:列表、元组、集合、字典,数据类型之间的 5 个差异 1. 相同点2. 不同点2.1 排序2.2 索引2.3 可变性2.5 允许的类型2.4 允许重复 源码 这篇博客将介绍列表、元组、集合、字典(lists, tuples, sets, and dictionaries)数据类型…...
redis学习笔记(四)
文章目录 list(数组)(1)添加子成员(2)基于索引获取列表成员(3)获取列表的切片(4)获取列表的长度(5)按索引设置值(6&#x…...
-L和-rpath-link和-rpath
知识点 现代连接器在处理动态库时将链接时路径(Link-time path)和运行时路径(Run-time path)分开,用户可以通过-L指定连接时库的路径,通过-R(或-rpath)指定程序运行时库的路径,大大提…...

chatGPT小白快速入门培训课程-001
一、前言 本文是《chatGPT小白快速入门培训课程》的第001篇文章,全部内容采用chatGPT和chatGPT开源平替软件生成。完整内容大纲详见:《chatGPT小白快速入门课程大纲》。 本系列文章,参与: AIGC征文活动 #AIGC技术创作内容征文# …...

【Linux操作系统】深入理解Linux系统编程中的传入参数、传出参数和传入传出参数
在Linux系统编程中,函数的参数扮演着至关重要的角色。参数的传递方式可以分为传入参数、传出参数和传入传出参数。本文将详细解释这三种参数的概念、特点以及如何使用它们来实现灵活和高效的函数调用和数据传递。 文章目录 1. 解释和举例1.1 传入参数(i…...
(二)结构型模式:3、过滤器模式(Filter、Criteria Pattern)(C++示例)设计模式
目录 1、过滤器模式(Filter、Criteria Pattern)含义 2、过滤器模式应用场景 3、过滤器模式主要几个关键角色 4、C实现过滤器模式的示例 1、过滤器模式(Filter、Criteria Pattern)含义 (1)过滤器模式是…...

欧拉OS 使用 CentOS 7 yum repo
一、下载CentOS的repo的yum文件 任何基于CentOS的yum的repo 的url是这样的: 但欧拉OS输出这个变量为:openEuler 20.03 (LTS-SP3) 那明显欧拉想要使用这个yum的url找不到这个版本, 所以直接讲这个变量替换为 7, Centos 7的7 然后执行&…...

C进阶(1/7)——数据在内存中的存储
目录 前言: 一.数据类型介绍 类型基本归类: 整型家族: 浮点数家族: 构造类型: 指针类型: 空类型: 二.整型在内存中的存储 1.原码,反码,补码 2.大小端介绍 3.练…...

如何初始化Git仓库
如何将目录初始化为Git仓库 一级目录二级目录三级目录 一、准备1、安装 gh2、登录 二、初始化 Git 仓库 一级目录 二级目录 三级目录 一、准备 在这里,我们需要借助一个非常好用的工具,大家也可以参照官方文档进行阅读,下面介绍常用的…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文通过代码驱动的方式,系统讲解PyTorch核心概念和实战技巧,涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...