【Linux】进程间通信(IPC)-- 无名管道、命名管道
IPC机制 实现进程间通信
在多个进程间传输数据或共享信息的机制。
数据交换,共享资源,进程同步,消息传递。
IPC实现原理:通信进程能够访问相同的内存区域。
方法:
管道:无名管道pipe、命名管道FIFO
System V IPC:消息队列、信号量、共享内存
POSIX IPC :消息队列、信号量、共享内存
套接字:socket
一、无名管道pipe
在有父子关系或者有亲缘关系的进程之间通信
字节流通信,数据格式由用户定义/解析
单向通信(半双工模式),数据单向流动(在管道中同时读写会发生错误)
1.创建无名管道 pipe
两种形式
int pipe( int fd[2] ) ;int pipe( int fd[2] , int flags);
int fd[2]:整型数组,存储管道的文件描述符;fd[0] 读文件描述符,fd[1] 写文件描述符
int flags: 设置管道标志的参数,0或以下参数的按位和:
O_NONBLOCK 非阻塞 读管道或写管道时不会阻塞管道
O_CLOEXEC 设置当在execve系统调用执行时关闭管道
返回值:
成功 返回 0
失败 返回 -1,并设置errno
2.写管道write
#define TEST_STRING "123456789"void write( fd[1] , TEST_STRING , sizeof(TEST_STRING));
写端fd[1],将TEST_STRING代表的字符写入管道,长度为 sizeof(TEST_STRING)
3.读管道read
char rbuf[100]={0};void read( fd[0] , rbuf , 100);
读端fd[0] , 将管道中的数据读到rbuf中,每次读100个字符长度
4.关闭管道 close
关闭读端
close(fd[0]);
关闭写端
close(fd[1]);
5.实现父子进程间的半双工通信
以下是父进程和子进程通信,父进程写,子进程读:

无名管道一般跟fork()函数搭配使用。
第一步,调用pipe函数,生成pipeinnode文件节点,生成管道。
第二步,调用fork函数,父进程创建子进程,同时父进程中的文件表也会拷贝到子进程,此时子进程也可以通过fd4,fd5文件描述符访问管道。
第三步,关闭父进程的读端(fd[0]),关闭子进程的写端(fd[1])。
此时父子进程就可以通过管道进行通信。
PS:pipe一定要在fork之前
创建pipe_test文件
vi pipe_test.c
pipe_test文件代码实现
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int fd[2]={};//存储pipe的文件描述符
void pipe_test()
{pid_t pid=fork();//创建子进程if(pid==0)//子进程{ printf("children\n");close(fd[1]);//子进程关闭写端while(1){//读数据char rbuf[100]={0};read(fd[0],rbuf,100);printf("rbuf:%s\n",rbuf);}close(fd[0]);//读完数据关闭读端}else if(pid>0)//父进程{printf("parent\n");close(fd[0]);//父进程关闭读端#define TEST_STRING "1234567890"while(1){write(fd[1],TEST_STRING,sizeof(TEST_STRING));sleep(1);}close(fd[1]);}}else{}
}int main(int argc,char * argv[])
{int ret=pipe(fd);//创建管道if(ret==-1)//创建管道失败{perror("pipe error");//设置errnoreturn -1;}pipe_test();//调用函数return 0;
}
退出 分别按下按键 Esc : w q
编译 pipe_test文件
gcc -o pipe_test pipe_test.c
运行
./pipe_test
结果
6.实现父子进程间的全双工通信
如图,父进程和子进程之间能够交换数据,双方都可以向对方写数据和读数据。

第一步,父进程调用两次pipe,创建两个管道。
第二步,父进程调用fork,创建子进程,此时子进程有和父进程相同的文件表,也有两个管道的文件描述符。
第三步,父进程只保留 管道1的读端 和 管道2的写端,
子进程只保留管道1的写端 和 管道2的读端。
二、命名管道FIFO
无名管道只能在具有亲缘关系的进程之间传递数据,如果想要在不相关的进程之间传递数据,可以使用 FIFO文件 即 “命名管道” (通常也被称为 “有名管道”)完成这项任务。
命名管道是一种特殊类型的文件(别忘了Linux中所有事物都是文件),它在文件系统中以文件名形式存在。文件标识为“p”。
【Linux其他文件类型可查看博客 【Linux】Linux中七种文件类型-CSDN博客】
1.创建FIFO文件
创建FIFO文件 可以在命令行上创建,也可以在程序中创建
(1)在命令行中创建命名管道
在命令行中创建管道也有两种方式
① mkfifo filename
mkfifo filename
filename 是FIFO文件的文件名
② mknod filename p
mknod filename p
filename 是FIFO文件的文件名
p表示创建的是管道文件
(2)在程序中创建命名管道
在程序中也有两个函数可以创建命名管道
注意添加头文件
#include <sys/types.h>
#include <sys/stat.h>
① int mkfifo(filename , mode)
int mkfifo (const char * filename , mode_t mode) ;
const char * filename :表示FIFO文件的文件名
mode_t mode :表示该FIFO文件的文件权限,如可读、可写、可执行
命名管道的权限由 mkfifo 的 mode 参数和 umask 共同决定。
如 mkfifo(fifo_path, 0666); // 实际权限为 0666 & ~umask
② int mknod(filename , mode | S_IFIFO , 0)
对于这个函数,作者也不太懂,只是看到书上提到了,所以也在这里提出来。对于一般要求可以不掌握。
int mknod (const char * filename , mode_t mode | S_IFIFO , (dev_t) 0) ;
举例:
创建 fifo_test.c文件
vi fifo_test.c
fifo_test.c文件
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
int fifo_test()
{const char* fifo_path="./myfifo";int ret=mkfifo(fifo_path,0777);if(ret<0){printf("create myfifo failure\n");}printf("create myfifo sucessed\n");return 0;
}
int main(int argc,char * argv[])
{fifo_test();return 0;
}
退出 分别按下按键 Esc : w q
编译 fifo_test文件
gcc -o fifo_test fifo_test.c
运行
./fifo_test
结果

(在后面的文章中,作者将不再赘叙关于编译运行文件的命令)
2.打开FIFO文件 open
打开FIFO的一个限制是,程序不能以O_RDWR模式(即可读可写模式)打开FIFO文件进行读写操作,这样做的后果未明确定义。但是这个限制是有道理的,如果一个管道以读/写方式打开,那么进程就会从这个管道中读取到它自己写入的数据。
通常使用FIFO文件是为了单向传递数据,要实现全双工模式,跟上文提到的无名管道一样,可以使用一对FIFO文件(即两个FIFO文件)。
int open( const char * filepath , int oflags) ;
const char * filepath : FIFO文件的路径名
int oflags : 有O_RDONLY ,O_WRONLY ,O_NONBLOCK 三种参数可选可组合(O_RDWR已被排除),共有四种组合方式:
O_RDONLY : 只读模式。这种情况下open调用将阻塞,除非有一个进程以写的方式打开同一个FIFO,否则将不会返回。
O_RDONLY | O_NONBLOCK :非阻塞读。即便没有其他进程以写的方式调用FIFO,这个open调用也会成功并立刻返回
O_WRONLY : 只写模式。这种情况下open调用将阻塞,除非有一个进程以读的方式打开同一个FIFO,否则将不会返回。
O_WRONLY | O_NONBLOCK :非阻塞写。如果没有其他进程以读的方式调用FIFO,这个open调用将返回错误码-1,并且FIFO也不会打开。如果有一个进程以读的方式打开FIFO文件,就可以通过它的返回的文件描述符对这个FIFO文件进行写操作。
注意:O_NONBLOCK搭配 O_RDONLY和O_WRONLY的效果是不同的。
非阻塞读的open调用总是成功的。
如果没有进程以读的方式打开FIFO文件,那么非阻塞写的open调用将失败。
3.写FIFO文件 write
int pipe_fd = open(FIFO_NAME , open_mode) ; //pipe_fd 为FIFO文件的文件描述符#define BUFFER_SIZE PIPE_BUFchar buffer[BUFFER_SZIE + 1] ;write( pipe_fd , buffer , BUFFER_SIZE) ;
将 buffer 传入 文件描述符为pipe_fd的命名管道中 , 长度为BUFFER_SIZE。
成功返回0,失败返回-1。
系统对任意时刻在一个FIFO中可以存在的数据长度所有限制的。它由#define PIPE_BUF 语句定义,通常可以在头文件limits.h 中找到它。在Linux系统中,它的值一般为4096字节。
4.读FIFO文件 read
read函数的用法同write,就是在需要在另一个进程中使读函数。
ret = read(pipe_fd , buffer , BUFFER_SIZE);
5.实现两进程之间的命名管道通信
(1)在命令行中之间使用FIFO通信
① 新建一个myfifo 文件
mkfifo myfifo
② 打开一个终端,将FIFO文件中的内容输出
cat < ./myfifo
③ 打开另一个终端,往FIFO文件中输入
echo "hello world" > ./myfifo
④ 查看两进程

(2)在程序中使用FIFO通信
fifocom.c文件
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/wait.h>
void *writer(void *arg)
{printf("ww : writer begin\n");const char * fifo_path="./myfifo";int fd = open(fifo_path , O_WRONLY);if(fd==-1){printf("ww: open fifo failure\n");exit(-1);}char * s="hello from writer\n";write(fd,s ,strlen(s));close(fd);printf("ww : close writer\n");return NULL;
}
void *reader(void * arg)
{printf("rr : reader begin\n");const char * fifo_path="./myfifo";int fd = open(fifo_path, O_RDONLY);if(fd==-1){printf("ww: open fifo failure\n");exit(-1);}char buff[100];read(fd, buff, sizeof(buff));printf("rr recived: %s\n",buff);close(fd);printf("rr : close reader\n");return NULL;
}
int main(int argc,char * argv[])
{printf("everything is ok------\n");pthread_t read_thread,write_thread;pthread_create(&read_thread , NULL , reader ,NULL);pthread_create(&write_thread , NULL , writer ,NULL);pthread_join(read_thread ,NULL);pthread_join(write_thread ,NULL);wait(NULL);return 0;
}
结果:

相关文章:
【Linux】进程间通信(IPC)-- 无名管道、命名管道
IPC机制 实现进程间通信 在多个进程间传输数据或共享信息的机制。 数据交换,共享资源,进程同步,消息传递。 IPC实现原理:通信进程能够访问相同的内存区域。 方法: 管道:无名管道pipe、命名管道FIFO S…...
每日一题-力扣-2278. 字母在字符串中的百分比 0331
字母在字符串中的百分比求解方案 | 力扣 2278 题解 问题描述 给定一个字符串 s 和一个字母 letter,我们需要计算 letter 在 s 中出现的百分比,并将结果向下取整。例如,如果字符串是 "foobar",字母是 "o"&…...
【分布式】深入剖析 Sentinel 限流:原理、实现
在当今分布式系统盛行的时代,流量的剧增给系统稳定性带来了巨大挑战。Sentinel 作为一款强大的流量控制组件,在保障系统平稳运行方面发挥着关键作用。本文将深入探讨 Sentinel 限流的原理、实现方案以及其优缺点,助力开发者更好地运用这一工具…...
[leetcode]2492. 两个城市间路径的最小分数(并查集 排序后建边)
题目链接 题意 给定一个 n n n个点 m m m条边的无向图 每条边有边权 求1-n的路径中最小的边权是多少 每条路可以重复走 思路 把边按边权降序排序 用并查集维护连通性 遍历每条边 每次合并边的起点和终点 如果1和n联通 并且这条边在1和n的这个连通块中 就对ans取min Code…...
关于CodeJava的学习笔记——11
一、GUI 1、最简单的GUI 只有一个按钮的GUI import java.awt.*; import javax.swing.*; public class SimpleGUI{JFrame frame;Button bt;public SimpleGUI(){frame new JFrame("标题栏内容");bt new Button("点我啊");frame.add(bt);frame.setSize(8…...
首个物业plus系列展 2025上海国际智慧物业博览会开幕
AI赋能服务升级!首个“物业plus”系列展 2025上海国际智慧物业博览会盛大开幕 3月31日,2025上海国际智慧物业博览会(简称“上海物博会”)在上海新国际博览中心N4馆隆重开幕。本届展会由广州旭杨国际展览有限公司主办,…...
嵌入式八股文学习——虚函数相关知识学习
虚函数 什么是虚函数?虚函数示例解析代码解析: 使用虚函数的注意事项1. 虚函数的声明与定义2. 派生类中的虚函数 哪些函数不能声明为虚函数1. 普通函数(非成员函数)2. 构造函数3. 内联成员函数4. 静态成员函数5. 友元函数总结 纯虚…...
rk3586开发版新增系统调用(Android13)
一、前言 最近想学一下kernel和hal,所以买了一块板子,带了个摄像头和屏幕,1100,学习投资了。这个Android内核定一个系统调用感觉是真的麻烦,主要是有一层bionic C,一开始不熟悉的时候还是花了点时间去配置。 二、kernel修改 include/uapi/asm-generic…...
OCR第三个方案:PP-OCRv4的初步探索
一、PP-OCR历史简要回顾 先请出PP-OCR官网,理解上有出入的,以官网为准。 1.1 PP-OCR系列历史 PP-OCRv1(2020):首创3.5M超轻量模型,奠定两阶段架构基础(检测方向分类识别)PP-OCRv2…...
物联网开发项目:AS608+ESP32S3+Vue构建指纹识别系统(二)——ESP32部分
一、前言 接着上一篇文章介绍的关于AS608模块的介绍以及关于指纹特征库的提取与导入分析,如果亲自上手了的话,那么对于Arduino IDE和AS608的基本操作已经熟悉了。 在这一个月之中,抛开中途有事耽误了,终于是基本上完成了我们整个项…...
程序化广告行业(46/89):竞价结算规则、底价策略与内部排名解析
程序化广告行业(46/89):竞价结算规则、底价策略与内部排名解析 大家好!在之前的几篇博客中,我们已经深入探讨了程序化广告的多个重要方面,从基础概念到实际操作流程。我写这些博客的目的,就是希…...
ICLR 2025 Spotlight:让机器人实现「自主进化」,蚂蚁数科、清华提出具身协同框架 BodyGen
最近,全球 AI 和机器学习顶会 ICLR 2025 公布了论文录取结果:由蚂蚁数科与清华大学联合团队提出的全新具身协同框架 BodyGen 成功入选 Spotlight(聚光灯/特别关注)论文。 论文出自蚂蚁数科与清华大学兴军亮老师团队合作的科研项目…...
第十九章:Python-pyttsx3 库实现文本转语音功能
前言 在开发语音交互应用或需要文本转语音功能的项目时,pyttsx3 是一个非常实用的 Python 库。它支持离线语音合成,无需联网即可将文本转换为语音。本文将详细介绍 pyttsx3 的功能、用法以及常见问题的解决方法,并通过示例代码帮助你快速上手…...
Unity 2022.3.x部分Android设备播放视频黑屏问题
Android平台视频兼容性问题很多…类似的黑屏问题真的很头大,总结一些常见问题: 1. 视频文件不支持压缩 如果使用AssetBundle加载视频,这个AssetBundle压缩格式要选None。有人可能会说最新版Unity已经支持bundle压缩下播放视频,稳…...
vLLM 部署 openai whisper 模型实现语音转文字
vLLM 部署 openai whisper 模型实现语音转文字 1. 安装 vLLM2. 启动 openai whisper 模型 1. 安装 vLLM pip install vllm vllm[audio] --pre --extra-index-url https://wheels.vllm.ai/nightly --upgrade2. 启动 openai whisper 模型 CUDA_VISIBLE_DEVICES0 \ VLLM_WORKER_…...
【Zabbix技术系列文章】第④篇——Zabbix 数据可视化
在当今数字化运维时代,面对海量的监控数据,如何从中快速获取有价值的信息至关重要。Zabbix 的数据可视化功能为我们提供了直观、高效的解决方案,它能将复杂的监控数据转化为清晰易懂的图表和仪表盘,助力运维人员迅速发现问题、分析…...
表格数据导出为Excel
环境及插件配置:(理论上vue2应该也可以使用,没有试验过) "vue": "^3.2.36", "webpack": "^5.94.0", "webpack-cli": "^5.1.4", "file-saver": "^2.…...
Faster-Whisper —— 为语音识别加速的利器
Faster-Whisper —— 为语音识别加速的利器 在语音识别技术迅速发展的今天,OpenAI 的 Whisper 模型因其强大的多语言识别能力和优异的准确率而受到广泛关注。然而,高精度模型往往伴随着高昂的计算开销和较长的推理时间,这对于需要实时或大规…...
SvelteKit 最新中文文档教程(16)—— Service workers
前言 Svelte,一个语法简洁、入门容易,面向未来的前端框架。 从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1: Svelte …...
Flutter项目之构建打包分析
目录: 1、准备部分2、构建Android包2.1、配置修改部分2.2、编译打包 3、构建ios包3.1、配置修改部分3.2、编译打包 1、准备部分 2、构建Android包 2.1、配置修改部分 2.2、编译打包 执行flutter build apk命令进行打包。 3、构建ios包 3.1、配置修改部分 3.2、编译…...
24、网络编程基础概念
网络编程基础概念 网络结构模式MAC地址IP地址子网掩码端口网络模型协议网络通信的过程(封装与解封装) 网络结构模式 C/S结构,由客户机和服务器两部分组成,如QQ、英雄联盟 B/S结构,通过浏览器与服务器进程交互…...
Mentalab Explore Pro携手 Wearanize + 数据集,推动睡眠科学研究
在神经科学和睡眠研究的领域,精确监测大脑活动是获取深入见解的关键。传统多导睡眠监测(PSG)设备虽然提供了详尽的数据,但其操作的复杂性和成本限制了其在更广泛场景中的应用。可穿戴技术的兴起提供了一种新的数据收集方式&#x…...
基于 RK3588 的 YOLO 多线程推理多级硬件加速引擎框架设计(代码框架和实现细节)
一、前言 接续上一篇文章,这个部分主要分析代码框架的实现细节和设计理念。 基于RK3588的YOLO多线程推理多级硬件加速引擎框架设计(项目总览和加速效果)-CSDN博客https://blog.csdn.net/plmm__/article/details/146542002?spm1001.2014.300…...
element-ui图片查看器
element-ui图片查看器 调用案例: <el-image-viewerv-if"showViewer":on-close"()>{showViewerfalse}":url-list"imgList" />export default {components: {Banner,el-image-viewer:()>import(element-ui/packages/image/…...
VoIP技术及其与UDP的关系详解
随着互联网的飞速发展,基于IP的语音通信技术(Voice over Internet Protocol,简称VoIP)已经成为现代通信的重要支柱。从Skype到Zoom,从企业电话系统到智能音箱,VoIP以其低成本、高灵活性和强大的扩展性逐渐取…...
Java中如何保证高并发的数据安全
在Java中保证高并发的数据安全,可以从以下几个方面入手: 1. 锁机制 • synchronized:Java内置的锁机制,用于同步方法或代码块,简单易用,但灵活性较低。 • ReentrantLock:提供了比synchronize…...
DeepSeek原生稀疏注意力(Native Sparse Attention, NSA)算法介绍
李升伟 整理 DeepSeek 提出的原生稀疏注意力(Native Sparse Attention, NSA)算法是一种创新的注意力机制,旨在解决大语言模型(LLM)在处理长序列数据时的计算瓶颈问题。NSA 通过结合算法优化和硬件对齐设计,…...
Java基础知识总结(1.8)——Java 注解(持续更新)
更新时间:2025-03-31 Web后端专栏:CSDN专栏——理论-Web后端技术博客总目录:计算机技术系列博客——目录页 8.1 注解的概念 8.1.1 定义与作用 Java注解(Annotation)是Java语言自JDK1.5版本引入的核心特性࿰…...
【Yolov8部署】 VS2019+opencv+onnxruntime 环境下部署目标检测模型
文章目录 前言一、导出yolov8模型为onnx文件二、VS2019中环境配置三、源码与实际运行 前言 本文主要研究场景为工业场景下,在工控机与工业相机环境中运行的视觉缺陷检测系统,因此本文主要目的为实现c环境下,将yolov8已训练好的检测模型使用o…...
论文阅读:Dual Anchor Graph Fuzzy Clustering for Multiview Data
论文地址:Dual Anchor Graph Fuzzy Clustering for Multiview Data | IEEE Journals & Magazine | IEEE Xplore 代码地址:https://github.com/BBKing49/DAG_FC 摘要 多视角锚图聚类近年来成为一个重要的研究领域,催生了多个高效的方法。然而&#…...
