Linux- pipe()系统调用
管道
管道(Pipe)是一种用于进程间通信(IPC)的简单而有效的方式。在UNIX和类UNIX操作系统(如Linux)中,管道提供了一种让一个进程将其输出发送给另一个进程的输入的机制。管道通常用于数据流的单向传输。
在底层,管道其实是一个由操作系统内核维护的缓冲区。一个进程向管道的一端(写端)写入数据,而另一个进程可以从管道的另一端(读端)读取数据。
管道实现的基本思想
- 缓冲区管理:内核维护一个缓冲区,这个缓冲区用于存储写入管道的数据。
- 同步与互斥:内核还提供了同步和互斥机制,以保证数据能够安全地从一个进程传输到另一个进程。
- 文件描述符:从用户态的角度来看,管道其实就是一对文件描述符,其中一个用于读,另一个用于写。
pipe()
在UNIX-like操作系统中,pipe()
系统调用用于创建一个新的管道,这是一种允许两个进程进行单向数据传输的IPC(进程间通信)机制。一个进程写入管道的一端,而另一个进程从管道的另一端读取。
函数原型
管道是通过以下函数原型创建的:
#include <unistd.h>
int pipe(int pipefd[2]);
参数
pipefd
: 这是一个包含两个int
型元素的数组。函数调用成功时,pipefd[0]
将成为管道的读取端(read end)的文件描述符,而pipefd[1]
将成为管道的写入端(write end)的文件描述符。
返回值
- 成功:返回0。
- 失败:返回-1,并设置
errno
。
工作原理
-
数据流向:数据从
pipefd[1]
(写端)流向pipefd[0]
(读端)。 -
阻塞和非阻塞:
pipe()
通常是阻塞的。也就是说,读操作会阻塞,直到有数据写入;写操作也会阻塞,直到读端读取了数据。 -
数据缓冲:数据首先被写入内核缓冲区,然后由读操作从缓冲区中读取。
-
文件描述符的继承:
pipe()
创建的文件描述符可以在fork()
之后由子进程继承,这使得pipe()
非常适用于父子进程或兄弟进程之间的通信。 -
关闭规则:当写端被关闭后,任何尝试从读端读取的操作将立即返回,读取到的数据长度为0(表示EOF)。当读端被关闭后,任何尝试写入写端的操作都将导致发送
SIGPIPE
信号。
应用场景
管道经常用在多进程应用中,例如shell命令中的管道操作符|
,它允许一个命令的输出可以作为另一个命令的输入。
综上所述,pipe()
是一种在两个进程之间简单有效地传输数据的低级IPC机制。然而,它有局限性,如仅能进行单向通信,且通常用于有共同祖先的进程之间。
示例
下面的C程序示例演示了如何使用pipe()
,fork()
和read()/write()
函数来实现简单的进程间通信。这个例子中,父进程向管道中写入字符串,子进程从管道中读取并打印这个字符串。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>int main() {int pipefd[2];pid_t pid;// 创建管道if (pipe(pipefd) == -1) {perror("pipe");exit(EXIT_FAILURE);}// 创建子进程pid = fork();if (pid == -1) {perror("fork");exit(EXIT_FAILURE);}if (pid == 0) { // 子进程char buffer[128];close(pipefd[1]); // 关闭不需要的写端// 从管道读取数据read(pipefd[0], buffer, sizeof(buffer));printf("Child read: %s\n", buffer);close(pipefd[0]); // 关闭读端exit(EXIT_SUCCESS);} else { // 父进程const char *msg = "Hello, Pipe!";close(pipefd[0]); // 关闭不需要的读端// 写入数据到管道write(pipefd[1], msg, strlen(msg) + 1);printf("Parent wrote: %s\n", msg);close(pipefd[1]); // 关闭写端// 等待子进程结束wait(NULL);}return 0;
}
代码解析
-
创建管道:使用
pipe(pipefd)
创建一个新的管道。成功后,pipefd[0]
是读端,pipefd[1]
是写端。 -
创建子进程:使用
fork()
创建一个新的进程。 -
父进程:
- 关闭读端,因为父进程只需要写。
- 使用
write()
将字符串写入管道。 - 关闭写端。
-
子进程:
- 关闭写端,因为子进程只需要读。
- 使用
read()
从管道中读取数据。 - 打印读取的数据。
- 关闭读端。
-
父进程等待:父进程使用
wait(NULL)
等待子进程结束。
这就是一个简单的使用pipe()
进行进程间通信的例子。运行这个程序,应该会看到类似下面的输出:
Parent wrote: Hello, Pipe!
Child read: Hello, Pipe!
这表明父进程写入的数据成功地被子进程读出。
【注】当一个进程(父进程)调用fork()
创建子进程时,子进程会继承父进程的文件描述符表。这意味着pipefd[0]
和pipefd[1]
在子进程中的值将与父进程中的值相同,它们指向同一个管道。
具体地说,父进程和子进程将拥有指向同一个内核管道对象的文件描述符。这使得父子进程可以通过这个管道进行通信。
因为子进程继承了父进程的文件描述符,所以:
- 在子进程中,
pipefd[0]
仍然是管道的读端。 - 在子进程中,
pipefd[1]
仍然是管道的写端。
这就是为什么在创建管道和fork()
之后,通常会看到一些close()
调用:每个进程通常只需要管道的一端,所以会关闭不需要的那一端。这样做有助于避免潜在的死锁和资源泄漏。
例如,在上面的示例代码中:
- 子进程关闭了写端(
close(pipefd[1]);
),因为它只从管道中读取数据。 - 父进程关闭了读端(
close(pipefd[0]);
),因为它只向管道中写入数据。
这种做法使得管道更容易管理,并且可以确保当所有的写端或读端被关闭时,相关的操作(如read()
和write()
)能够正确地返回。
相关文章:
Linux- pipe()系统调用
管道 管道(Pipe)是一种用于进程间通信(IPC)的简单而有效的方式。在UNIX和类UNIX操作系统(如Linux)中,管道提供了一种让一个进程将其输出发送给另一个进程的输入的机制。管道通常用于数据流的单…...

数据库常用指令
检查Linux系统是否已经安装了MySQL: sudo service mysql start...
[Studio]Manifest merger failed with multiple errors, see logs 解决方法
记录一个引入库时经常会出错的问题 最近使用一个图片上传库后项目代码报了一个错: Execution failed for task :app:processDebugManifest. > Manifest merger failed with multiple errors, see logs* Try: Run with --info or --debug option to get more lo…...

【数据结构与算法】不就是数据结构
前言 嗨喽小伙伴们你们好呀,好久不见了,我已经好久没更新博文了!之前因为实习没有时间去写博文,现在已经回归校园了。我看了本学期的课程中有数据结构这门课程(这么课程特别重要),因为之前学过一点…...

封装一个高级查询组件
封装一个高级查询组件 背景一,前端相关代码二,后端相关代码三,呈现效果总结 背景 业务有个按照自定义选择组合查询条件,保存下来每次查询的时候使用的需求。查了一下项目里的代码没有现成的组件可以用,于是封装了一个 …...
代码随想录第七章 栈与队列
1、leecode232 用栈实现队列 使用栈模拟队列的行为,仅使用一个栈是不行的,所以需要两个栈,一个是输入栈,一个是输出栈。 #include<iostream> #include<vector> #include<string> #include<stack> #incl…...
SQL Server对象类型(5)——4.5. 同义词(Synonym)
4.5. 同义词(Synonym) 4.5.1. 同义词概念 与Oracle中相同,SQL Server中的同义词是虚的、被定义的模式对象,其本身并不存储任何数据。其用途之一就是为其他类型基础对象提供一个别名;用途之二就是为应用提供一个抽象层,以方便后期应用相关的基础对象的更改和维护。用户可…...

IP风险查询:抵御DDoS攻击和CC攻击的关键一步
随着互联网的普及,网络攻击变得越来越普遍和复杂,对企业和个人的网络安全构成了重大威胁。其中,DDoS(分布式拒绝服务)攻击和CC(网络连接)攻击是两种常见且具有破坏性的攻击类型,它们…...

Tune-A-Video论文阅读
论文链接:Tune-A-Video: One-Shot Tuning of Image Diffusion Models for Text-to-Video Generation 文章目录 摘要引言相关工作文生图扩散模型文本到视频生成模型文本驱动的视频编辑从单个视频生成 方法前提DDPMsLDMs 网络膨胀微调和推理模型微调基于DDIM inversio…...
Dataset和DataLoader用法
Dataset和DataLoader用法 在d2l中有简洁的加载固定数据的方式,如下 d2l.load_data_fashion_mnist() # 源码 Signature: d2l.load_data_fashion_mnist(batch_size, resizeNone) Source: def load_data_fashion_mnist(batch_size, resizeNone):"""…...

【跟小嘉学习区块链】二、Hyperledger Fabric 架构详解
系列文章目录 【跟小嘉学习区块链】一、区块链基础知识与关键技术解析 【跟小嘉学习区块链】一、区块链基础知识与关键技术解析 文章目录 系列文章目录[TOC](文章目录) 前言一、Hyperledger 社区1.1、Hyperledger(面向企业的分布式账本)1.2、Hyperledger社区组织结构 二、Hype…...
springboot下spring方式实现Websocket并设置session时间
概述 springboot实现websocket有4种方式 servlet,spring,netty,stomp 使用下来spring方式是最简单的. springboot版本:3.1.2 jdk:17 当前依赖版本 <dependency><groupId>org.springframework.boot<…...

LeetCode算法二叉树—相同的树
目录 100. 相同的树 - 力扣(LeetCode) 代码: 运行结果: 给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是…...

搭建Flink集群、集群HA高可用以及配置历史服务器
Flink集群搭建 Flink集群搭建集群规划下载并解压安装包修改集群配置分发安装目录启动集群访问Web UI Flink集群HA高可用概述集群规划配置flink配置master、workers配置ZK分发安装目录启动HA集群测试 Flink参数配置配置历史服务器概述配置启动、停止历史服务器提交一个Job任务查…...

vscode终端中打不开conda虚拟包管理
今天,想着将之前鸽的Unet网络模型给实现一下,结果发现,在vscode中运行python脚本,显示没有这包,没有那包。但是在其他的ipynb中是有的,感觉很奇怪。我检查了一下python版本,发现不是我深度学习的…...

【音视频】MP4封装格式
基本概念 使用MP4box.js查看MP4内部组成结构 整体结构 数据索引(moov)数据流包(mdat) 各个包的位置,大小,信息,时间戳,编码方式等全在数据索引 数据流包只有纯二进制码流数据 数据…...
环境-使用vagrant快速创建linux虚拟机
1.下载软件 虚拟机 Oracle VM VirtualBox 镜像 Vagrant by HashiCorp (vagrantup.com) 如果下载慢,可以复制下载链接,使用迅雷下载 2.安装 根据提示点击下一步即可,建议安装到空间较大的非系统盘。 打开 window cmd 窗口,…...

10.1网站编写(Tomcat和servlet基础)
一.Tomcat: 1.Tomcat是java写的,运行时需要依赖jre,所以要装jdk. 2.建议配置好环境变量. 3.默认端口号8080(业务端口)可能会被占用,建议改一下(本人改成了9999). 4.另一个默认端口是8005(管理端口). 二Servlet基础(编写一个hello world代码): 整体分为7个步骤,分别是创建…...

10CQRS
本系列包含以下文章: DDD入门DDD概念大白话战略设计代码工程结构请求处理流程聚合根与资源库实体与值对象应用服务与领域服务领域事件CQRS(本文) 案例项目介绍 # 既然DDD是“领域”驱动,那么我们便不能抛开业务而只讲技术&…...

DAZ To UMA⭐一.DAZ简单使用教程
文章目录 🟥 DAZ快捷键🟧 DAZ界面介绍 🟥 DAZ快捷键 移动物体:ctrlalt鼠标左键 旋转物体:ctrlalt鼠标右键 导入模型:双击左侧模型UI 🟧 DAZ界面介绍 Files:显示全部文件 Products:显示全部产品 Figures:安装的全部人物 Wardrobe…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...

企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...

使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...