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

【Linux】进程间通信之管道

【Linux】进程间通信之管道

  • 进程间通信
    • 进程间通信目的
    • 进程间通信的方式
  • 管道(内核维护的缓冲区)
    • 匿名管道(用于父子间进程间通信)
      • 简单使用
      • 阻塞状态读写特征
      • 非阻塞状态读写特征
    • 匿名管道特点
    • 命名管道
  • 匿名管道与命名管道的区别

进程间通信

进程之间具有独立性,进程间通信必定需要一块公共的区域用来作为信息的存放点,操作系统需要直接的或间接给通信进程双方提供内存空间。
如果内存空间是文件系统提供的,那么就是管道通信
如果OS提供的就是共享内存
通信的本质就是让不同的进程看到同一份内存空间

进程间通信目的

数据传输:一个进程需要将它的数据发送给另一个进程

资源共享:多个进程之间共享同样的资源

通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)

进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程)

进程间通信的方式

管道: 匿名管道命名管道
System V:System V 消息队列;System V 共享内存;System V 信号量
POSIX:消息队列;共享内存;信号量;互斥量;条件变量;读写锁

管道(内核维护的缓冲区)

管道是基于文件系统的通信方式

任何一个文件包括两套资源:
1.file的操作方法
2.有属于自己的内核缓冲区,所以父进程和子进程有一份公共的资源:文件系统提供的内核缓冲区,父进程可以向对应的文件的文件缓冲区写入,子进程可以通过文件缓冲区读取,此时就完成了进程间通信,这种方式提供的文件称为管道文件。管道文件本质就是内存级文件,不需要IO。

匿名管道(用于父子间进程间通信)

通过父进程fork创建子进程,让子进程拷贝父进程中的文件描述符表,两个进程便能看到同一个管道文件,这个管道文件是一个内存级文件,并没有名字,所以被称为匿名管道
在这里插入图片描述

匿名管道中,父子进程必须关闭一个文件描述符,形成单向通信

简单使用

#include <unistd.h>
int pipe(int pipefd[2]);
fd:文件描述符数组,其中fd[0]表示读端, fd[1]表示写端
成功时返回零,错误时返回 -1
#include <iostream>
#include <unistd.h>
#include <cassert>
#include <cstring>
#include <sys/wait.h>
#include <sys/types.h>
using namespace std;
//父进程进行读取,子进程负责写入
int main()
{//第一步:创建管道文件,打开读写端//fds[0]读   fds[1]写int fds[2];int n=pipe(fds);assert(n==0);//forkpid_t id=fork();assert(id>=0);if(id==0){//子进程写入,先关闭读close(fds[0]);//子进程通信代码const char* s="我是子进程,我正在给你发信息";int cnt=0;while (true){cnt++;char buffer[1024];//只有子进程能访问//格式化写入snprintf(buffer,sizeof(buffer),"chile->parent say: %s[%d][%d]",s,cnt,getpid());//子进程向【fd[1]】不断写,父进程【fd[0]】延迟读,导致写阻塞write(fds[1],buffer,strlen(buffer));//cout<<"count"<<cnt<<endl;//sleep(5);//延迟写,父进程read阻塞//break;//写一次直接关闭读端,读端read返回0,}//出来还是子进程close(fds[1]);//子进程关闭写端fdcout<<"子进程关闭了自己的写端"<<endl;exit(0);}//父进程读取close(fds[1]);//父进程通信代码while(true){//sleep(3000);//写端不断写,读端延迟读,写端阻塞//sleep(2);//写端不断写,读端缓读,数据积累在一起被读出char buffer[1024];//如果管道中没有数据,读端在读,默认阻塞当前读进程由R->S状态//cout<<"parent_read_begin..."<<endl;ssize_t s= read(fds[0],buffer,sizeof(buffer)-1);//阻塞式调用//cout<<"parent_read_end..."<<endl;if(s>0){buffer[s]=0;cout<<"父进程读到了# "<<buffer<<" | my_pid: "<<getpid()<<endl;}else if(s==0){//读到了文件末尾cout<<"read: over "<<s<<endl;break;}break;//读一次直接退出,父进程准备关闭读端,os会发送信号杀掉写进程}//读未关闭// n=waitpid(id,nullptr,0);// assert(n==id);// close(fds[0]);//关闭读端,程序无效close(fds[0]);cout<<"父进程关闭写端"<<endl;int status=0;n=waitpid(id,&status,0);获取进程终止信号cout<<"waitpid->"<<n<<" : "<<(status&0x7f)<<endl;return 0;
}

阻塞状态读写特征

1)如果管道中没有数据,读取端进程再进行读取,会阻塞当前正在读取的进程

2)如果写入端写满了,再写就会对该进程进行阻塞,需要等待对方对管道内数据进行读取

3)如果写入进程关闭了写入fd,读取端将管道内的数据读完后read的返回值为0,正常退出

4)如果读关闭,写就没有意义了,操作系统会给写端发送13号信号SIGPIPE,终止写端。(信号参考)

非阻塞状态读写特征

创建的匿名管道默认是阻塞状态的,如果要设置成非阻塞状态,需要使用fcntl
第一种:写设置为非阻塞
1)读端不关闭,写端一直写,写满之后,wirte会返回-1,报错当前资源不可用
2)读端直接关掉,写端一直在写,当前进程会收到SIGPIPE信号,写端的程序直接被杀死,这种现象叫做管道破裂
第二种:读设置为非阻塞
1)写端不关闭,读端一直读,read调用返回-1,errno为EAGAIN
2)写端关闭,读端进行读,read是正常调用返回0,表示没有读到

匿名管道特点

1)只能用于具有共同祖先的进程(具有亲缘关系的进程)之间进行通信;通常,一个管道由一个进程创建,然后该进程调用fork,此后父、子进程之间就可应用该管道;

2)管道提供流式服务 ;

3)进程退出,管道释放,所以管道的生命周期随进程

4)内核会对管道操作进行同步与互斥

5)管道是半双工。需要双方通信时,需要建立起两个管道
6)管道的大小是64K(65536)
7)创建匿名管道返回的文件描述符属性默认是阻塞的

命名管道

上面说到,匿名管道只能用于具有共同祖先的进程(具有亲缘关系的进程)之间进行通信,两个不相关的进程如果要通信,需要借助命名管道

创建命名管道

int mkfifo(const char *pathname, mode_t mode);
pathname:命名管道文件所在路径
mode:文件权限

删除命名管道

#include <unistd.h>
int unlink(const char *path);

命名管道可用于无血缘关系的进程间通信,两个进程均打开同一路径下的同名文件(看到同一份资源);命名管道也是一个内存级文件


comm.hpp(提供命名管道的创建和销毁方法)

#pragma once
#include <iostream>
#include <string>
#include <cstring>
#include <cerrno>
#include <cassert>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define NAMED_PIPE "./myname_pipe"bool CreateFifo(const std::string &path)
{umask(0);int n=mkfifo(path.c_str(),0600);if(n==0)return true;else{std::cout<<"errno: "<< errno <<"err string: "<<strerror(errno)<<std::endl;return false; }    
}void removeFifo(const std::string &path)
{int n=unlink(path.c_str());assert(n==0);std::cout<<"removeFifo success ...."<<std::endl;(void)n;//避免爆出waring:未引用的变量n
}

server.cc(读端,先运行)

#include "comm.hpp"int main()
{bool r=CreateFifo(NAMED_PIPE);assert(r);(void)r;//先运行此文件,会在open时阻塞//管道文件要求读写都要打开文件才能执行后面的功能std::cout<< "server begin" <<std::endl;int rfd=open(NAMED_PIPE,O_RDONLY);std::cout<< "server end" <<std::endl;if(rfd<0) exit(1);//readchar buffer[1024];while (true){ssize_t s=read(rfd,buffer,sizeof(buffer)-1);if(s>0){buffer[s]=0;std::cout<<"cilent ->server# "<<buffer<<std::endl;}else if(s==0){std::cout<<"cilent quit,me tool "<<std::endl;break;}else{std::cout<<"err string: "<<strerror(errno)<<std::endl;break;}}close(rfd);sleep(10);removeFifo(NAMED_PIPE);return 0;}

client.c(写端)

#include "comm.hpp"int main()
{//如果先运行此文件,由于文件还未创建,无法写入std::cout << "client begin" << std::endl;int wfd=open(NAMED_PIPE,O_WRONLY);std::cout<< "client end" <<std::endl;if(wfd<0) exit(1);//writechar buffer[1024];while (true){std::cout<<"Please Say#";fgets(buffer,sizeof buffer,stdin);if(strlen(buffer)>0)buffer[strlen(buffer)-1]=0;ssize_t n=write(wfd,buffer,strlen(buffer));assert(n==strlen(buffer));(void)n;    }close(wfd);return 0;}

匿名管道与命名管道的区别

1)匿名管道由pipe函数创建并打开。
2)命名管道由mkfifo函数创建,打开用open
3)FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完成之后,它们具有相同的语义

相关文章:

【Linux】进程间通信之管道

【Linux】进程间通信之管道 进程间通信进程间通信目的进程间通信的方式 管道&#xff08;内核维护的缓冲区&#xff09;匿名管道&#xff08;用于父子间进程间通信&#xff09;简单使用阻塞状态读写特征非阻塞状态读写特征 匿名管道特点命名管道 匿名管道与命名管道的区别 进程…...

记录一个正则表达式

正则表达式要求如下: 至少 8 个字符&#xff1b; 至少包含一个小写英文字母&#xff1b; 至少包含一个大写英文字母&#xff1b; 至少包含一个数字&#xff1b; 至少包含一个特殊字符&#xff0c;特殊字符为&#xff1a;“!#$%^&*()-” 中的一个&#xff1b; 不包含2个连续…...

用于全局复根和极点查找算法的自适应网格生成器(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

修改Linux中SSH的端口

文章目录 修改Linux中SSH的端口Linux中默认的ssh端口关闭SELinux测试新端口 修改Linux中SSH的端口 Linux中默认的ssh端口 使用root用户操作 修改前先备份ssh_config cp /etc/ssh/sshd_config /etc/ssh/sshd_config_date "%Y%m%d%H%M%S"修改配置文件&#xff0c;找…...

Ansible从入门到精通【六】

大家好&#xff0c;我是早九晚十二&#xff0c;目前是做运维相关的工作。写博客是为了积累&#xff0c;希望大家一起进步&#xff01; 我的主页&#xff1a;早九晚十二 专栏名称&#xff1a;Ansible从入门到精通 立志成为ansible大佬 ansible templates 模板&#xff08;templa…...

国企的大数据岗位方向的分析

现如今大数据已无所不在&#xff0c;并且正被越来越广泛的被应用到历史、政治、科学、经济、商业甚至渗透到我们生活的方方面面中&#xff0c;获取的渠道也越来越便利。 今天我们就来聊一聊“大屏应用”&#xff0c;说到大屏就一定要聊到数据可视化&#xff0c;现如今&#xf…...

【MySQL--->数据类型】

文章目录 [TOC](文章目录) 一、数据类型分类二、整型类型三、bit(位)类型四、float类型五、decimal类型六、char和varchar类型1.char类型2.varchar3.char与varchar的区别 七、日期与时间类型八、enum和set 一、数据类型分类 二、整型类型 数值类型有数据存储上限,而且每个类型都…...

Ceph部署

一、存储基础 1&#xff09;单机存储设备 ●DAS&#xff08;直接附加存储&#xff0c;是直接接到计算机的主板总线上去的存储&#xff09; IDE、SATA、SCSI、SAS、USB 接口的磁盘 所谓接口就是一种存储设备驱动下的磁盘设备&#xff0c;提供块级别的存储 ●NAS&#xff08;…...

打工日记-Vue3+Ts二次封装el-table

el-table是elementUI中的表格组件&#xff0c;在后台把管理系统中&#xff0c;也是一个比较常用的组件&#xff0c;目前有一个比较好的开源项目ProTable&#xff0c;这个项目做的很好&#xff0c;集成了搜索&#xff0c;表格&#xff0c;分页器功能很强大。但在我的实际使用中也…...

funbox3靶场渗透笔记

funbox3靶场渗透笔记 靶机地址 https://download.vulnhub.com/funbox/Funbox3.ova 信息收集 fscan找主机ip192.168.177.199 .\fscan64.exe -h 192.168.177.0/24___ _/ _ \ ___ ___ _ __ __ _ ___| | __/ /_\/____/ __|/ __| __/ _ |/ …...

springcloud3 hystrix实现服务降级,熔断,限流以及案例配置

一 hystrix的作用 1.1 降级&#xff0c;熔断&#xff0c;限流 1.服务降级&#xff1a; A方案出现问题&#xff0c;切换到兜底方案B&#xff1b; 2.服务熔断&#xff1a;触发规则&#xff0c;出现断电限闸&#xff0c;服务降级 3.服务限流&#xff1a;限制请求数量。 二 案例…...

ComponentOne Studio ASP.NET MVC Crack

ComponentOne Studio ASP.NET MVC Crack FlexReport增强功能 添加了对在Microsoft Windows上部署Microsoft Azure的支持。 添加了对显示嵌入字体的支持。 .NET标准版的经典C1PDF(Beta版) GrapeCity的经典C1Pdf库现在提供了基于Microsoft.NET标准的版本。在任何.NET应用程序(包括…...

OPENCV C++(十一)

鼠标响应函数 //鼠标响应函数 void on_mouse(int EVENT, int x, int y, int flags, void* userdata) {Mat hh;hh *(Mat*)userdata;switch (EVENT){case EVENT_LBUTTONDOWN:{vP.x x;vP.y y;drawMarker(hh, vP, Scalar(255, 255, 255));//circle(hh, vP, 4, cvScalar(255, 255…...

ES使用心得

客户端 Transport Client已经快要废弃了&#xff0c;官方推荐使用High Level REST Client。 常用命令 启停 systemctl start elasticsearch systemctl stop elasticsearch节点状态 curl http://myservice1:9200/_cat/nodes?vip heap.percent ram.percent cpu l…...

Stable Diffusion - 幻想 (Fantasy) 风格与糖果世界 (Candy Land) 人物提示词配置

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/132212193 图像由 DreamShaper8 模型生成&#xff0c;融合糖果世界。 幻想 (Fantasy) 风格图像是一种以想象力为主导的艺术形式&#xff0c;创造了…...

部署K8S集群

目录 一、环境搭建 1、准备环境 2、安装master节点 3、安装k8s-master上的node 4、安装配置k8s-node1节点 5、安装k8s-node2节点 6、为所有node节点配置flannel网络 7、配置docker开启加载防火墙规则允许转发数据 二、k8s常用资源管理 1、创建一个pod 2、pod管理 一、…...

在时间和频率域中准确地测量太阳黑子活动及使用信号处理工具箱(TM)生成广泛的波形,如正弦波、方波等研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

一百五十四、Kettle——Linux上安装Kettle9.3(踩坑,亲测有效,附截图)

一、目的 由于kettle8.2在Linux上安装后&#xff0c;共享资源库创建遇到一系列问题&#xff0c;所以就换成kettle9.3 二、kettle版本以及安装包网盘链接 kettle9.3.0安装包网盘链接 链接&#xff1a;https://pan.baidu.com/s/1MS8QBhv9ukpqlVQKEMMHQA?pwddqm0 提取码&…...

PackageNotFoundError: No package metadata was found for bitsandbytes解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

uni-app和springboot完成前端后端对称加密解密流程

概述 使用对称加密的方式实现。前端基于crypto-js。uni-app框架中是在uni.request的基础上&#xff0c;在拦截器中处理的。springboot在Filter中完成解密工作。 uni-app 项目中引入crypto-js。 npm install crypto-js加密方法 const SECRET_KEY CryptoJS.enc.Utf8.parse(…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…...

Golang——7、包与接口详解

包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解

一、前言 在HarmonyOS 5的应用开发模型中&#xff0c;featureAbility是旧版FA模型&#xff08;Feature Ability&#xff09;的用法&#xff0c;Stage模型已采用全新的应用架构&#xff0c;推荐使用组件化的上下文获取方式&#xff0c;而非依赖featureAbility。 FA大概是API7之…...