Linux 进程的管道通信
文章目录
- 无名管道pipe
- 有名管道
进程之间的通信:Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另外一个进程中都看不到,所以进程之间不能相互访问,要交换数据必须通过内核。如图,在内核中开辟一块缓冲区,进程1把数据从用户空间拷贝到内核缓冲区,进程2在从内核缓冲区中把数据读走,内核提供的这种机制称为进程间通信IPC(InterProcess Communication)

- 管道是LInux/Unix最经典的一种通信方式,管道实质上是父子进程借助内存文件的一种通信方式。借助进程映像加载等手段,它可以实现两个程序之间的数据交换。
- 管道的本质是一块内核缓冲区,由两根文件描述符引用,一个表示读端,一个表示写端,规定数据从管道的写端流入管道,从读端流出。当两根进程都终结的时候,管道会自动消失。默认的,管道的读端和写端都是堵塞的。
- 管道包括两种:无名管道和有名管道。
无名管道pipe
使用无名管道时,还可以搭配使用close()关闭文件描述符和dup()复制管道文件描述符来实现输入输出标准的重定向。
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>int main(){int data_processed;int file_pipes[2];const char some_data[]="123";char buffer[BUFSIZ+1];memset(buffer,'\0',sizeof(buffer));if(pipe(file_pipes)==0){data_processed=write(file_pipes[1],some_data,strlen(some_data));printf("Wrote %d bytes\n",data_processed);data_processed=read(file_pipes[0],buffer,BUFSIZ);printf("Read %d bytes:%s\n",data_processed,buffer);exit(EXIT_SUCCESS);}exit(EXIT_FAILURE);
}
[cch@aubin os]$ gcc demo.c
[cch@aubin os]$ ./a.out
Wrote 3 bytes
Read 3 bytes:123
[cch@aubin os]$
menset是c语言的初始化函数,作用是将某一块内存中的内容全部设置为指定的值,这个函数通常为新申请的内存做初始化工作。void *memset(void *s, int ch, size_t n);将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。int pipe(int fd[2])用于创建一个管道,如果函数调用成功,fd[0]存放管道的读端,fd[1]存放管道的写端(都是文件描述符),并且返回0,如果失败则返回-1,并设置errno值。
当父进程使用pipe创建管道之后,一般需要再fork一个子进程,然后通过管道实现父子进程之间的通信。一般来说只要两个进程有血缘关系(有共同的祖先),就可以使用管道进行通信。
- 父进程创建管道
- 父进程fork子进程
- 父进程关闭读端,子进程关闭写端,实现进程之间通信
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>int main(){int data_processed;int file_pipes[2];const char some_data[]="123";char buffer[BUFSIZ+1];pid_t fork_result;memset(buffer,'\0',sizeof(buffer));if(pipe(file_pipes)==0){fork_result=fork();if(fork_result==-1){fprintf(stderr,"Fork failure");exit(EXIT_FAILURE);}//子进程if(fork_result==0){data_processed=read(file_pipes[0],buffer,BUFSIZ);printf("son:Read %d bytes:%s\n",data_processed,buffer);exit(EXIT_SUCCESS);}else{data_processed=write(file_pipes[1],some_data,strlen(some_data));printf("father:Wrote %d bytes\n",data_processed);}exit(EXIT_SUCCESS);}exit(EXIT_FAILURE);
}
[cch@aubin os]$ gcc demo.c
[cch@aubin os]$ ./a.out
father:Wrote 3 bytes
son:Read 3 bytes:123
[cch@aubin os]$
管道实现程序之间的通信
//pipe4.c
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>int main(int argc,char *argv[]){int data_processed;char buffer[BUFSIZ+1];int file_descriptor;memset(buffer,'\0',sizeof(buffer));sscanf(argv[1],"%d",&file_descriptor);//读取格式化的argv[1]给file_descriptordata_processed=read(file_descriptor,buffer,BUFSIZ);printf("%d-read %d bytes:%s\n",getpid(),data_processed,buffer);exit(EXIT_FAILURE);}
# 0表示键盘,从键盘中读取输入并且输出
[cch@aubin os]$gcc pipe4.c -o pipe
[cch@aubin os]$ ./pipe 0
123466
4947-read 7 bytes:123466[cch@aubin os]$
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>int main(){int data_processed;int file_pipes[2];const char some_data[]="123";char buffer[BUFSIZ+1];pid_t fork_result;memset(buffer,'\0',sizeof(buffer));if(pipe(file_pipes)==0){fork_result=fork();if(fork_result==-1){fprintf(stderr,"Fork failure");exit(EXIT_FAILURE);}//子进程if(fork_result==0){sprintf(buffer,"%d",file_pipes[0]);//将file_pipes[0]转换成字符串,以适应execl调用中参数类型的要求,其中fotmat参数与print中的类型一致/*execlp("ls", "ls", "-l", "-F", NULL); 使用程序名在PATH中搜索。execl("/bin/ls", "ls", "-l", "-F", NULL); 使用参数1给出的绝对路径搜索。*/if(execl("pipe","pipe",buffer,(char *)0)==-1)printf("execl error\n");exit(EXIT_FAILURE);}else{data_processed=write(file_pipes[1],some_data,strlen(some_data));printf("father:Wrote %d bytes\n",data_processed);}exit(EXIT_SUCCESS);}exit(EXIT_FAILURE);
}
[cch@aubin os]$ gcc demo.c
[cch@aubin os]$ ./a.out
father:Wrote 3 bytes
argv[1]=3
6098-read 3 bytes:123
[cch@aubin os]$
有名管道
有名管道可以实现两个没有血缘关系的进程进行通信。
[cch@aubin s]$ mkfifo pp
[cch@aubin s]$ ls -la
总用量 44
drwxrwxr-x. 2 cch cch 80 11月 7 11:01 .
drwxr-xr-x. 5 cch cch 72 10月 14 20:04 ..
-rwxrwxr-x. 1 cch cch 14176 10月 23 19:09 a.out
-rw-r--r--. 1 cch cch 12288 10月 14 17:17 .cc.c.swp
-rw-------. 1 cch cch 12288 10月 12 17:05 .file1.c.swp
-rw-rw-r--. 1 cch cch 206 11月 7 11:00 file.c
prw-rw-r--. 1 cch cch 0 11月 7 11:01 pp
可以看到,当使用mkfifo创建有名管道后,管道文件的信息的第一个显示为
p,表示其为管道文件
[cch@aubin s]$ echo "hhhhsjiqq">pp
在命令行内输入以上,一开始管道会堵塞,因为它会等待一个进程读取数据
[cch@aubin s]$ cat pp
hhhhsjiqq
[cch@aubin s]$
相关文章:
Linux 进程的管道通信
文章目录 无名管道pipe有名管道 进程之间的通信:Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另外一个进程中都看不到,所以进程之间不能相互访问,要交换数据必须通过…...
OpenGL和Vulkan比较
比较 见参考 参考 Reference GuidesCopyright 2022-2023 The Khronos Group Inc. :: Vulkan Documentation ProjectDifference Between OpenGL vs VulkanVulkan与OpenGL对比——Vulkan的全新渲染架构 图形程序接口:OpenGL、OpenCL、Vulkan、OpenGL ES、WebGL…...
OpenCV入门3:像素操作
在OpenCV中,图像的像素值是以一个多维数组的形式表示的。上一篇已经介绍了cv::Mat类。对于图像中的每一个像素,可以通过Mat对象中的at<type>(i,j)函数(type可以是uchar、int等)获得Mat对象的像素值。 访问像素值࿱…...
使用内网穿透工具,远程测试本地接口
学习目标: 目标 含义: 内网穿透工具是一种能够帮助没有公网IP或者动态IP用户进行远程访问内网应用的工具。通过内网穿透,用户无论身处任何网络环境,都可以方便地访问企业内部的ERP、OA、CRM等应用。内网穿透工具还支持默认的Htt…...
uniapp小程序才到第五层就报错navigateto:fail webview count limit exceed
错误截图 原因 小程序官方描述是说可以跳转10层,但是使用uniapp开发的程序在小程序中才运行到第五层就报错了,原因是因为没有设置appId。如果设置了就正常了。...
【C++】map set
map & set 一、关联式容器二、键值对三、树形结构的关联式容器1. set(1)set 的介绍(2)set 的使用 2. multiset3. map(1)map 的介绍(2)map 的使用 4. multimap 四、map 和 set 的…...
正点原子嵌入式linux驱动开发——Linux Regmap驱动
在前面学习I2C和SPI驱动的时候,针对I2C和SPI设备寄存器的操作都是通过相关的API函数进行操作的。这样Linux内核中就会充斥着大量的重复、冗余代码,但是这些本质上都是对寄存器的操作,所以为了方便内核开发人员统一访问I2C/SPI设备的时候&…...
京东商品详情API,页面信息采集,优惠券信息获取
京东开放平台提供了API接口来访问京东商品详情。通过这个接口,您可以获取到商品的详细信息,如商品名称、价格、库存量、描述等。额外还附加一个优惠券信息接口。代码如下: 京东获得JD商品详情 API 优惠券接口 公共参数 名称类型必须描述keyString是调…...
Visual Studio 2022 + OpenCV 4.5.2 安装与配置教程
目录 OpenCV的下载与配置Visual Studio 2022的配置新建工程新建文件新建项目属性表环境配置测试先写一个输出将OpenCV的动态链接库添加到项目的 x64 | Debug下测试配置效果 Other OpenCV的下载与配置 参考这个OpenCV的下载与环境变量的配置: Windows10CLionOpenCV4…...
docker 安装 mysql (单体架构)
文章归档:https://www.yuque.com/u27599042/coding_star/nckzqa73g47hgz3x 查询 MySQL 镜像 docker search mysql拉取 MySQL 镜像 docker pull mysql在宿主机创建映射目录 mkdir -p \ /home/docker/mysql/log \ /home/docker/mysql/data \ /home/docker/mysql/co…...
城市内涝怎么预警?万宾科技内涝积水监测仪
在城市运行过程中,城市内涝问题频繁出现,影响城市管理水平的提升,也会进一步减缓城市基础设施建设。尤其近几年来,城市内涝灾害频繁出现,在沿海地区内涝所带来的安全隐患成为城市应急管理部门的心头大患。城市内涝的背…...
Spring基础(2):放弃XML,走向注解
上一篇并没有实际地带大家去看源码,而是介绍了两个概念: BeanDefinitionBeanPostProcessor 当然,我介绍得非常笼统,不论是BeanDefinition还是BeanPostProcessor其实都有着较为复杂的继承体系,种类也很多。作为Spring…...
【线性代数】分块矩阵总结
...
Redis-命令操作Redis->redis简介,redis的安装(Linux版本windows版本),redis的命令
redis简介redis的安装(Linux版本&windows版本)redis的命令 1.redis简介 Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。 它支持字符串、哈…...
17、Python虚拟环境:为何要用虚拟环境、如何使用virtualenv
文章目录 在Python开发中,虚拟环境是一个独立的目录树,可以在其中安装Python模块。每个虚拟环境都有自己的Python二进制文件和一组安装的库。使用虚拟环境的主要原因是为了避免项目间的依赖冲突,允许每个项目有其特定的依赖,而不影响全局安装的模块。 为何要用虚拟环境 依…...
elasticSearch 接口实现查询热词统计
前面讲过使用elasticsearch可视化工具可以直接写语法查询如下: GET robot-demand/_search { "size":10, //查询多少条数据 "aggs":{ "hot_words":{ "terms":{ "field": "title" } }…...
10年测试经验分享:新手如何找到适合自己的软件测试项目?
每一个测试新手(特别是自学测试的人)来说,往往不知道到哪里去找项目练手,这应该是最大的困扰了。 实话讲,这个目前没有非常好的、直接的解决办法,不过在这我可以结合我自己之前的一些工作经历,…...
【MySQL】查询语句
文章目录 选择语句 / 子句比较运算符AND,OR,NOT运算符IN运算符BETWEEN运算符LIKE运算符REGEXP运算符 选择语句 / 子句 USE:选择使用的databaseSELECT:选择查询的列FROM:选择查询的表WHERE:条件查询ORDER B…...
金蝶云星空的网络控制设置
文章目录 金蝶云星空的网络控制设置说明网控参数加入网络控制清除网络控制清除网络控制(单个)清除网络控制(批量)清除网络控制(批量,参数是拼接好的业务对象) 金蝶云星空的网络控制设置 说明 …...
linux服务器国内源安装nvm,又快又方便
国内安装nvm的话,如果你的服务器不能访问github,那么使用gitee快速安装还是很方便的: # 能方位github的话,使用这条命令 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | bash# 不能访问github的话…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...


