【Linux操作系统】详解Linux系统编程中的管道进程通信
在Linux系统编程中,管道是一种常用的进程间通信方式。它可以实现父子进程之间或者兄弟进程之间的数据传输。本文将介绍如何使用管道在Linux系统中进行进程通信,并给出相应的代码示例。

文章目录
- 1. 管道的概念
- 2. 管道的创建和使用
- 2.1 原型
- 2.2 示例
- 3. 父子进程通信
- 4. 兄弟进程间通信
- 5. fifo函数
- 6. fifo实现血缘关系进程间通信
- 7. 管道的特性和限制
- 8. 总结
1. 管道的概念
管道是一种特殊的文件,它提供了一个缓冲区用于进程间的数据传输。管道可以分为两种类型:匿名管道和命名管道。
- 匿名管道:匿名管道是一种临时的管道,只能在有亲缘关系的进程之间使用,通常用于父子进程之间的通信。匿名管道只能在创建它的进程及其子进程之间使用,其他进程无法访问。
- 命名管道:命名管道是一种有名字的管道,可以在不同的进程之间进行通信。命名管道通过在文件系统中创建一个文件来实现,进程可以通过该文件来读写数据。
在本文中,我们将重点介绍匿名管道的使用。
2. 管道的创建和使用
2.1 原型
在Linux系统中,可以使用pipe函数来创建一个管道。pipe函数的原型如下:
int pipe(int pipefd[2]);
pipefd是一个整型数组,用于存储管道的读写文件描述符。pipefd[0]用于读取管道中的数据,pipefd[1]用于写入管道中的数据。
2.2 示例
下面是一个简单的示例代码,演示了如何使用管道进行父子进程之间的通信:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>int main() {int pipefd[2];pid_t pid;char buf[1024];// 创建管道if (pipe(pipefd) == -1) {perror("pipe");exit(EXIT_FAILURE);}// 创建子进程pid = fork();if (pid == -1) {perror("fork");exit(EXIT_FAILURE);}if (pid == 0) {// 子进程写入数据到管道close(pipefd[0]); // 关闭读取端char* msg = "Hello, parent!";write(pipefd[1], msg, strlen(msg) + 1);close(pipefd[1]); // 关闭写入端exit(EXIT_SUCCESS);} else {// 父进程读取管道中的数据close(pipefd[1]); // 关闭写入端read(pipefd[0], buf, sizeof(buf));printf("Received message from child: %s\n", buf);close(pipefd[0]); // 关闭读取端exit(EXIT_SUCCESS);}
}
在上述代码中,首先使用pipe函数创建了一个管道。然后使用fork函数创建了一个子进程。子进程使用write函数将数据写入管道,父进程使用read函数从管道中读取数据。
3. 父子进程通信
父进程创建管道,并创建子进程后,父进程通过管道向子进程发送数据,子进程通过管道接收父进程发送的数据。
下面是一个示例代码,演示了父子进程之间使用管道进行通信的过程:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>int main() {int pipefd[2];pid_t pid;char buf[1024];// 创建管道if (pipe(pipefd) == -1) {perror("pipe");exit(EXIT_FAILURE);}// 创建子进程pid = fork();if (pid == -1) {perror("fork");exit(EXIT_FAILURE);}if (pid == 0) {// 子进程读取管道中的数据close(pipefd[1]); // 关闭写入端read(pipefd[0], buf, sizeof(buf));printf("Received message from parent: %s\n", buf);close(pipefd[0]); // 关闭读取端exit(EXIT_SUCCESS);} else {// 父进程写入数据到管道close(pipefd[0]); // 关闭读取端char* msg = "Hello, child!";write(pipefd[1], msg, strlen(msg) + 1);close(pipefd[1]); // 关闭写入端exit(EXIT_SUCCESS);}
}
在上述代码中,首先使用pipe函数创建了一个管道。然后使用fork函数创建了一个子进程。子进程使用read函数从管道中读取数据,父进程使用write函数将数据写入管道。
4. 兄弟进程间通信
要实现兄弟进程之间的通信,可以使用命名管道(named pipe)或者共享内存(shared memory)来实现。
-
使用命名管道(named pipe):
- 兄弟进程可以通过创建一个命名管道来进行通信。
- 一个兄弟进程将数据写入命名管道,另一个兄弟进程从命名管道中读取数据。
- 兄弟进程需要使用相同的命名管道名称来进行通信。
- 可以使用
mkfifo函数创建命名管道,使用open函数打开管道进行读写操作。
-
使用共享内存(shared memory):
- 兄弟进程可以通过创建一个共享内存区域来进行通信。
- 一个兄弟进程将数据写入共享内存,另一个兄弟进程从共享内存中读取数据。
- 兄弟进程需要使用相同的共享内存标识符来进行通信。
- 可以使用
shmget函数创建共享内存,使用shmat函数将共享内存附加到进程的地址空间中进行读写操作。
下面是一个使用命名管道的示例代码,演示了兄弟进程之间的通信过程:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>int main() {pid_t pid;char buf[1024];const char* fifoName = "/tmp/myfifo";// 创建命名管道mkfifo(fifoName, 0666);// 创建子进程pid = fork();if (pid == -1) {perror("fork");exit(EXIT_FAILURE);}if (pid == 0) {// 子进程从命名管道中读取数据int fd = open(fifoName, O_RDONLY);read(fd, buf, sizeof(buf));printf("Received message from sibling: %s\n", buf);close(fd);exit(EXIT_SUCCESS);} else {// 父进程向命名管道中写入数据int fd = open(fifoName, O_WRONLY);char* msg = "Hello, sibling!";write(fd, msg, strlen(msg) + 1);close(fd);exit(EXIT_SUCCESS);}
}
在上述代码中,首先使用mkfifo函数创建了一个命名管道。然后使用fork函数创建了一个子进程。子进程使用open函数打开命名管道并从中读取数据,父进程使用open函数打开命名管道并向其中写入数据。
5. fifo函数
下面是一个使用mkfifo和open函数的示例代码,演示了兄弟进程之间的通信过程:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>int main() {pid_t pid;char buf[1024];const char* fifoName = "/tmp/myfifo";// 创建命名管道mkfifo(fifoName, 0666);// 创建子进程pid = fork();if (pid == -1) {perror("fork");exit(EXIT_FAILURE);}if (pid == 0) {// 子进程从命名管道中读取数据int fd = open(fifoName, O_RDONLY);read(fd, buf, sizeof(buf));printf("Received message from sibling: %s\n", buf);close(fd);exit(EXIT_SUCCESS);} else {// 父进程向命名管道中写入数据int fd = open(fifoName, O_WRONLY);char* msg = "Hello, sibling!";write(fd, msg, strlen(msg) + 1);close(fd);exit(EXIT_SUCCESS);}
}
在上述代码中,首先使用mkfifo函数创建了一个命名管道。然后使用fork函数创建了一个子进程。子进程使用open函数打开命名管道并从中读取数据,父进程使用open函数打开命名管道并向其中写入数据。
6. fifo实现血缘关系进程间通信
下面是一个使用命名管道实现非血缘关系进程间通信的示例代码:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>int main() {pid_t pid;char buf[1024];const char* fifoName = "/tmp/myfifo";// 创建命名管道mkfifo(fifoName, 0666);// 创建子进程pid = fork();if (pid == -1) {perror("fork");exit(EXIT_FAILURE);}if (pid == 0) {// 子进程向命名管道中写入数据int fd = open(fifoName, O_WRONLY);char* msg = "Hello, sibling!";write(fd, msg, strlen(msg) + 1);close(fd);exit(EXIT_SUCCESS);} else {// 父进程从命名管道中读取数据int fd = open(fifoName, O_RDONLY);read(fd, buf, sizeof(buf));printf("Received message from sibling: %s\n", buf);close(fd);exit(EXIT_SUCCESS);}
}
在上述代码中,首先使用mkfifo函数创建了一个命名管道。然后使用fork函数创建了一个子进程。子进程使用open函数打开命名管道并向其中写入数据,父进程使用open函数打开命名管道并从中读取数据。
7. 管道的特性和限制
管道作为一种进程间通信方式,具有以下特性和限制:
- 管道是半双工的,即数据只能在一个方向上流动。
- 管道是有限长度的,一旦写满了数据,继续写入会被阻塞,直到有进程读取数据后才能继续写入。
- 管道只能在有亲缘关系的进程之间使用,即父子进程或者兄弟进程之间。
8. 总结
-
fifo函数:在C标准库中没有名为fifo的函数。 -
命名管道(FIFO):命名管道是一种特殊的文件,可以在文件系统中创建,并且可以被不同的进程打开和读写。使用
mkfifo函数可以创建命名管道。 -
兄弟进程间通信:兄弟进程是指由同一个父进程创建的多个子进程。兄弟进程间通信可以使用命名管道实现,其中一个进程向命名管道写入数据,另一个进程从命名管道读取数据。
-
非血缘关系进程间通信:非血缘关系的进程是指没有共同的父进程的进程。非血缘关系进程间通信同样可以使用命名管道实现,其中一个进程向命名管道写入数据,另一个进程从命名管道读取数据。
相关文章:
【Linux操作系统】详解Linux系统编程中的管道进程通信
在Linux系统编程中,管道是一种常用的进程间通信方式。它可以实现父子进程之间或者兄弟进程之间的数据传输。本文将介绍如何使用管道在Linux系统中进行进程通信,并给出相应的代码示例。 文章目录 1. 管道的概念2. 管道的创建和使用2.1 原型2.2 示例 3. 父…...
【Redis从头学-4】Redis中的String数据类型实战应用场景之验证码、浏览量、点赞量、Json格式存储
🧑💻作者名称:DaenCode 🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。 😎人生感悟:尝尽人生百味,方知世间冷暖。 📖所属专栏:Re…...
linux 统计命令
统计命令 使用wc来进行统计 # wc [选项] 文件名wc -l a 2 awc -w a 8 a---------------l 统计行数-w 统计单词数-m 统计字符数-c 统计字节数 https://zhhll.icu/2021/linux/基础/统计命令/ 本文由 mdnice 多平台发布...
docker部署springboot应用
一、下载安装docker curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun 启动:systemctl start docker 二、配置国内镜像源 (1)在/etc/docker目录中添加daemon.json文件,内容如下: { …...
YOLO v5、v7、v8 模型优化
YOLO v5、v7、v8 模型优化 魔改YOLOyaml 文件解读模型选择在线做数据标注 YOLO算法改进YOLOv5yolo.pyyolov5.yaml更换骨干网络之 SwinTransformer更换骨干网络之 EfficientNet优化上采样方式:轻量化算子CARAFE 替换 传统(最近邻 / 双线性 / 双立方 / 三线…...
回归预测 | MATLAB实现SSA-BP麻雀搜索算法优化BP神经网络多输入单输出回归预测(多指标,多图)
回归预测 | MATLAB实现SSA-BP麻雀搜索算法优化BP神经网络多输入单输出回归预测(多指标,多图) 目录 回归预测 | MATLAB实现SSA-BP麻雀搜索算法优化BP神经网络多输入单输出回归预测(多指标,多图)效果一览基本…...
QT的mysql(数据库)最佳实践和常见问题解答
涉及到数据库,首先安利一个软件Navicat Premium,用来查询数据库很方便 QMysql驱动是Qt SQL模块使用的插件,用于与MySQL数据库进行通信。要编译QMysql驱动,您需要满足以下条件: 您需要安装MySQL的客户端库和开发头文件…...
使用PyMuPDF库的PDF合并和分拆程序
PDF工具应用程序是一个使用wxPython和PyMuPDF库编写的简单工具,用于合并和分拆PDF文件。它提供了一个用户友好的图形界面,允许用户选择源文件夹和目标文件夹,并对PDF文件进行操作。 C:\pythoncode\blog\pdfmergandsplit.py 功能特点 选择文…...
Data Abstract for .NET and Delphi Crack
Data Abstract for .NET and Delphi Crack .NET和Delphi的数据摘要是一套或RAD工具,用于在.NET、Delphi和Mono中编写多层解决方案。NET和Delphi的数据摘要是一个套件,包括RemObjects.NET和Delphi版本的数据摘要。RemObjects Data Abstract允许您创建访问…...
Eclipse集成MapStruct
Eclipse集成MapStruct 在Eclipse中添加MapStruct依赖配置Eclipse支持MapStruct①安装 m2e-aptEclipse Marketplace的方式安装Install new software的方式安装(JDK8用到) ②添加到pom.xml 今天拿到同事其他项目的源码,导入并运行的时候抛出了异…...
采用pycharm在虚拟环境使用pyinstaller打包python程序
一年多以前,我写过一篇博客描述了如何虚拟环境打包,这一次有所不同,直接用IDE pycharm构成虚拟环境并运行pyinstaller打包 之前的博文: 虚拟环境venu使用pyinstaller打包python程序_伊玛目的门徒的博客-CSDN博客 第一步…...
Rx.NET in Action 中文介绍 前言及序言
Rx 处理器目录 (Catalog of Rx operators) 目标可选方式Rx 处理器(Operator)创建 Observable Creating Observables直接创建 By explicit logicCreate Defer根据范围创建 By specificationRangeRepeatGenerateTimerInterval Return使用预设 Predefined primitivesThrow …...
Azure Blob存储使用
创建存储账户,性能选择标准即可,冗余选择本地冗余存储即可 容器选择类别选择专用即可 可以上传文件到blob中 打开文件可以看到文件的访问路径 4.编辑中可以修改文件 复制链接,尝试访问,可以看到没有办法访问,因为创建容器的时候选…...
mysql、redis面试题
mysql 相关 1、数据库优化查询方法 外键、索引、联合查询、选择特定字段等等2、简述mysql和redis区别 redis: 内存型非关系数据库,数据保存在内存中,速度快mysql:关系型数据库,数据保存在磁盘中,检索的话&…...
22、touchGFX学习Model-View-Presenter设计模式
touchGFX采用MVP架构,如下所示: 本文界面如下所示: 本文将实现两个操作: 1、触摸屏点击开关按键实现打印开关显示信息,模拟开关灯效果 2、板载案按键控制触摸屏LED灯的显示和隐藏 一、触摸屏点击开关按键实现打印开…...
Python Opencv实践 - 图像高斯滤波(高斯模糊)
import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/pomeranian.png", cv.IMREAD_COLOR) rows,cols,channels img.shape print(rows,cols,channels)#为图像添加高斯噪声 #使用np.random.normal(loc0.0, scale1.0…...
使用 Qt 生成 Word 和 PDF 文档的详细教程
系列文章目录 文章目录 系列文章目录前言一、安装 Qt二、生成 Word 文档三、生成 PDF 文档四、运行代码并查看结果五、自定义文档内容总结 前言 Qt 是一个跨平台的应用程序开发框架,除了用于创建图形界面应用程序外,还可以用来生成 Word 和 PDF 文档。本…...
ssm+vue校园美食交流系统源码
ssmvue校园美食交流系统源码和论文026 开发工具:idea 数据库mysql5.7 数据库链接工具:navcat,小海豚等 技术:ssm 摘 要 随着现在网络的快速发展,网上管理系统也逐渐快速发展起来,网上管理模式很快融入到了许多商…...
电力系统基础知识(一)—电力系统概述
1、电压 也称作电势差或电位差,是衡量单位电荷在静电场中由于电势不同所产生的能量差的物理量。其大小等于单位正电荷因受电场力作用从A点移动到B点所做的功,电压的方向规定为从高电位指向低电位。其单位为伏特(V,简称伏),常用单位还有千伏(kV)、毫伏(mV)、微伏(uV…...
AzurLaneAutoScript:碧蓝航线玩家的终极自动刷图解决方案
AzurLaneAutoScript:碧蓝航线玩家的终极自动刷图解决方案 【免费下载链接】AzurLaneAutoScript Azur Lane bot (CN/EN/JP/TW) 碧蓝航线脚本 | 无缝委托科研,全自动大世界 项目地址: https://gitcode.com/gh_mirrors/az/AzurLaneAutoScript 还在为…...
MOOTDX:Python通达信数据接口的完整指南
MOOTDX:Python通达信数据接口的完整指南 【免费下载链接】mootdx 通达信数据读取的一个简便使用封装 项目地址: https://gitcode.com/GitHub_Trending/mo/mootdx MOOTDX是一个专为量化投资和股票数据分析设计的Python通达信数据接口封装库,它提供…...
ROS2 Galactic下源码编译TEB局部规划器:从依赖安装到成功运行Navigation2的保姆级避坑记录
ROS2 Galactic源码编译TEB局部规划器全流程实战指南 在机器人导航领域,TEB(Timed Elastic Band)局部规划器因其优秀的动态避障能力而备受青睐。然而当我们将目光转向ROS2 Galactic时,会发现官方仓库并未提供预编译的TEB功能包&…...
半小时搞定C#开发
前言 此篇发出的原因有两点 致敬C#开篇 - 孤独战士,一篇包含雄心壮志的开篇,便无疾而终,时隔这么多年回关,内心莫名欣慰,感谢曾经的自己,就像文章标题所说,做一个无谓的孤独战士。笔者看到现在…...
【计算机网络硬核指南】子网划分终极篇:定长+VLSM+超网三合一实战(3道大厂真题逐字节演算)
【计算机网络硬核指南】子网划分终极篇:定长VLSM超网三合一实战(3道大厂真题逐字节演算) 前言 在上一篇文章中,我们系统学习了IP地址基础和子网划分的核心方法,逐题演算了9道经典真题。很多读者反馈说,看…...
Hanime1Plugin终极指南:打造纯净Android动漫观影体验的免费神器
Hanime1Plugin终极指南:打造纯净Android动漫观影体验的免费神器 【免费下载链接】Hanime1Plugin Android插件(https://hanime1.me) (NSFW) 项目地址: https://gitcode.com/gh_mirrors/ha/Hanime1Plugin 你是否厌倦了在Android设备上看动漫时被各种广告打断&a…...
5分钟免费搭建PUBG终极雷达系统:实现战场全透视的完整指南
5分钟免费搭建PUBG终极雷达系统:实现战场全透视的完整指南 【免费下载链接】PUBG-maphack-map this is a working copy online-map from jussihi/PUBG-map-hack, use nodejs webserver instead of firebase. 项目地址: https://gitcode.com/gh_mirrors/pu/PUBG-ma…...
为什么83%的用户误读NotebookLM引用溯源?一文讲透证据链完整性校验四步法
更多请点击: https://intelliparadigm.com 第一章:为什么83%的用户误读NotebookLM引用溯源?一文讲透证据链完整性校验四步法 NotebookLM 的“引用溯源”功能并非传统意义上的文献标注,而是一套基于语义锚点与片段置信度的轻量级证…...
Python 开发者五分钟接入 Taotoken 调用 GPT 与 Claude 模型
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 Python 开发者五分钟接入 Taotoken 调用 GPT 与 Claude 模型 对于需要在项目中集成大语言模型的 Python 开发者而言,逐…...
Windows用户的救星:APK Installer让你在电脑上轻松运行Android应用
Windows用户的救星:APK Installer让你在电脑上轻松运行Android应用 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否曾经想在Windows电脑上体验Androi…...
