当前位置: 首页 > news >正文

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 117 11:01 .
drwxr-xr-x. 5 cch cch    72 1014 20:04 ..
-rwxrwxr-x. 1 cch cch 14176 1023 19:09 a.out
-rw-r--r--. 1 cch cch 12288 1014 17:17 .cc.c.swp
-rw-------. 1 cch cch 12288 1012 17:05 .file1.c.swp
-rw-rw-r--. 1 cch cch   206 117 11:00 file.c
prw-rw-r--. 1 cch cch     0 117 11:01 pp

可以看到,当使用mkfifo创建有名管道后,管道文件的信息的第一个显示为p,表示其为管道文件

[cch@aubin s]$ echo "hhhhsjiqq">pp

在命令行内输入以上,一开始管道会堵塞,因为它会等待一个进程读取数据

[cch@aubin s]$ cat pp
hhhhsjiqq
[cch@aubin s]$ 

相关文章:

Linux 进程的管道通信

文章目录 无名管道pipe有名管道 进程之间的通信&#xff1a;Linux环境下&#xff0c;进程地址空间相互独立&#xff0c;每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另外一个进程中都看不到&#xff0c;所以进程之间不能相互访问&#xff0c;要交换数据必须通过…...

OpenGL和Vulkan比较

​ 比较 见参考 参考 Reference GuidesCopyright 2022-2023 The Khronos Group Inc. :: Vulkan Documentation ProjectDifference Between OpenGL vs VulkanVulkan与OpenGL对比——Vulkan的全新渲染架构 图形程序接口&#xff1a;OpenGL、OpenCL、Vulkan、OpenGL ES、WebGL…...

OpenCV入门3:像素操作

在OpenCV中&#xff0c;图像的像素值是以一个多维数组的形式表示的。上一篇已经介绍了cv::Mat类。对于图像中的每一个像素&#xff0c;可以通过Mat对象中的at<type>(i,j)函数&#xff08;type可以是uchar、int等&#xff09;获得Mat对象的像素值。 访问像素值&#xff1…...

使用内网穿透工具,远程测试本地接口

学习目标&#xff1a; 目标 含义&#xff1a; 内网穿透工具是一种能够帮助没有公网IP或者动态IP用户进行远程访问内网应用的工具。通过内网穿透&#xff0c;用户无论身处任何网络环境&#xff0c;都可以方便地访问企业内部的ERP、OA、CRM等应用。内网穿透工具还支持默认的Htt…...

uniapp小程序才到第五层就报错navigateto:fail webview count limit exceed

错误截图 原因 小程序官方描述是说可以跳转10层&#xff0c;但是使用uniapp开发的程序在小程序中才运行到第五层就报错了&#xff0c;原因是因为没有设置appId。如果设置了就正常了。...

【C++】map set

map & set 一、关联式容器二、键值对三、树形结构的关联式容器1. set&#xff08;1&#xff09;set 的介绍&#xff08;2&#xff09;set 的使用 2. multiset3. map&#xff08;1&#xff09;map 的介绍&#xff08;2&#xff09;map 的使用 4. multimap 四、map 和 set 的…...

正点原子嵌入式linux驱动开发——Linux Regmap驱动

在前面学习I2C和SPI驱动的时候&#xff0c;针对I2C和SPI设备寄存器的操作都是通过相关的API函数进行操作的。这样Linux内核中就会充斥着大量的重复、冗余代码&#xff0c;但是这些本质上都是对寄存器的操作&#xff0c;所以为了方便内核开发人员统一访问I2C/SPI设备的时候&…...

京东商品详情API,页面信息采集,优惠券信息获取

京东开放平台提供了API接口来访问京东商品详情。通过这个接口&#xff0c;您可以获取到商品的详细信息&#xff0c;如商品名称、价格、库存量、描述等。额外还附加一个优惠券信息接口。代码如下: 京东获得JD商品详情 API 优惠券接口 公共参数 名称类型必须描述keyString是调…...

Visual Studio 2022 + OpenCV 4.5.2 安装与配置教程

目录 OpenCV的下载与配置Visual Studio 2022的配置新建工程新建文件新建项目属性表环境配置测试先写一个输出将OpenCV的动态链接库添加到项目的 x64 | Debug下测试配置效果 Other OpenCV的下载与配置 参考这个OpenCV的下载与环境变量的配置&#xff1a; Windows10CLionOpenCV4…...

docker 安装 mysql (单体架构)

文章归档&#xff1a;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…...

城市内涝怎么预警?万宾科技内涝积水监测仪

在城市运行过程中&#xff0c;城市内涝问题频繁出现&#xff0c;影响城市管理水平的提升&#xff0c;也会进一步减缓城市基础设施建设。尤其近几年来&#xff0c;城市内涝灾害频繁出现&#xff0c;在沿海地区内涝所带来的安全隐患成为城市应急管理部门的心头大患。城市内涝的背…...

Spring基础(2):放弃XML,走向注解

上一篇并没有实际地带大家去看源码&#xff0c;而是介绍了两个概念&#xff1a; BeanDefinitionBeanPostProcessor 当然&#xff0c;我介绍得非常笼统&#xff0c;不论是BeanDefinition还是BeanPostProcessor其实都有着较为复杂的继承体系&#xff0c;种类也很多。作为Spring…...

【线性代数】分块矩阵总结

...

Redis-命令操作Redis->redis简介,redis的安装(Linux版本windows版本),redis的命令

redis简介redis的安装&#xff08;Linux版本&windows版本&#xff09;redis的命令 1.redis简介 Redis是一个开源&#xff08;BSD许可&#xff09;&#xff0c;内存存储的数据结构服务器&#xff0c;可用作数据库&#xff0c;高速缓存和消息队列代理。 它支持字符串、哈…...

17、Python虚拟环境:为何要用虚拟环境、如何使用virtualenv

文章目录 在Python开发中,虚拟环境是一个独立的目录树,可以在其中安装Python模块。每个虚拟环境都有自己的Python二进制文件和一组安装的库。使用虚拟环境的主要原因是为了避免项目间的依赖冲突,允许每个项目有其特定的依赖,而不影响全局安装的模块。 为何要用虚拟环境 依…...

elasticSearch 接口实现查询热词统计

前面讲过使用elasticsearch可视化工具可以直接写语法查询如下: GET robot-demand/_search { "size":10, //查询多少条数据 "aggs":{ "hot_words":{ "terms":{ "field": "title" } }…...

10年测试经验分享:新手如何找到适合自己的软件测试项目?

每一个测试新手&#xff08;特别是自学测试的人&#xff09;来说&#xff0c;往往不知道到哪里去找项目练手&#xff0c;这应该是最大的困扰了。 实话讲&#xff0c;这个目前没有非常好的、直接的解决办法&#xff0c;不过在这我可以结合我自己之前的一些工作经历&#xff0c;…...

【MySQL】查询语句

文章目录 选择语句 / 子句比较运算符AND&#xff0c;OR&#xff0c;NOT运算符IN运算符BETWEEN运算符LIKE运算符REGEXP运算符 选择语句 / 子句 USE&#xff1a;选择使用的databaseSELECT&#xff1a;选择查询的列FROM&#xff1a;选择查询的表WHERE&#xff1a;条件查询ORDER B…...

金蝶云星空的网络控制设置

文章目录 金蝶云星空的网络控制设置说明网控参数加入网络控制清除网络控制清除网络控制&#xff08;单个&#xff09;清除网络控制&#xff08;批量&#xff09;清除网络控制&#xff08;批量&#xff0c;参数是拼接好的业务对象&#xff09; 金蝶云星空的网络控制设置 说明 …...

linux服务器国内源安装nvm,又快又方便

国内安装nvm的话&#xff0c;如果你的服务器不能访问github&#xff0c;那么使用gitee快速安装还是很方便的&#xff1a; # 能方位github的话&#xff0c;使用这条命令 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | bash# 不能访问github的话…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

深入理解Optional:处理空指针异常

1. 使用Optional处理可能为空的集合 在Java开发中&#xff0c;集合判空是一个常见但容易出错的场景。传统方式虽然可行&#xff0c;但存在一些潜在问题&#xff1a; // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...