Linux学习记录——십구 进程间通信(1) 管道

news2025/2/22 23:47:05

文章目录

  • 1、进程间通信介绍
    • 1、目的
    • 2、发展
  • 2、管道
    • 1、原理
    • 2、简单模拟实现
    • 3、总结
  • 3、匿名管道——控制进程
  • 4、命名管道
    • 1、原理
    • 2、模拟实现


1、进程间通信介绍

之前所学都是单个进程,多个进程之间如何运转?

1、目的

数据传输:一个进程需要将它的数据发送给另一个进程
资源共享:多个进程之间共享同样的资源。
通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止
时要通知父进程)。
进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另
一个进程的所有陷入和异常,并能够及时知道它的状态改变。

进程是有独立性的,这增加了通信的成本。要让两个不同的进程进行通信的前提条件就是让两个进程看到同一份资源。这是操作系统直接或间接提供的。

对于任何通信手段,都要先让不同的进程看到同一份资源,然后一方写入,一方读取来完成通信。

2、发展

管道
System V进程间通信
POSIX进程间通信

2、管道

1、原理

管道是Unix中最古老的进程间通信的形式。

我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”

可以同时创建多个进程,通过管道连接,它们的父进程也都一样,bash。

管道也是文件,一个文件以写方式打开管道,将自己的标准输出重定向到管道,另一头的文件以读方式打开管道,将自己的标准输入重定向到管道。

文件进程开始时,结构体里有文件描述符的表,指向各个文件,除此之外,还会打开一个匿名管道,这是一个操作系统提供的纯粹的内存文件,不需要刷新内容到磁盘。通过进程调用,这个匿名管道会通过读和写打开同一个文件;当前进程会fork一下,把自己的文件描述符表拷贝给子进程,具体的内容会有对应更改,那打开的文件等需要拷贝吗?不拷贝。但没关系,因为文件描述表的原因,子进程依然指向父进程创建好的文件,包含那个匿名管道。这其实也相当于一个浅拷贝。父子进程指向的文件一样。所以父子都指向那个匿名管道,一方更改,一方就能得到新数据;不过这时候管道只支持单向通信,接下来要做的是确定数据流向,关闭不需要的fd。操作系统会把子进程的写方式和父进程的读方式都关掉,这样父写子读,就形成了一个管道。

管道确实只能单向通信,如果想要双向,就定义两个管道。

2、简单模拟实现

简单的代码,子进程向父进程发消息,就是一种管道。

 10 int main()
 11 {
 12     int pipefd[2] = {0};
 13     //1、创建管道
 14     int n = pipe(pipefd);
 15     if(n < 0)
 16     {
 17         std::cout << "pipe error, " << errno << ":" << strerror(errno) << std::endl;
 18         return 1;
 19     }
 20     std::cout << "pipefd[0]: " << pipefd[0] << std::endl;
 21     std::cout << "pipefd[1]: " << pipefd[0] << std::endl;
 22     //2、创建子进程
 23     pid_t id = fork();
 24     assert(id != -1);
 25     if(id == 0)
 26     {
 27         //3、关闭不需要的fd,让父进程进行读取,让子进程进行写入
 28         close(pipefd[0]);
 29         //4、开始通信
 30         const std::string namestr = "hello, 我是子进程";
 31         int cnt = 1;
 32         char buffer[1024];
 33         while(true)
 34         {
 35             snprintf(buffer, sizeof(buffer), "%s, 计数器: %d, 我的PID: %d\n", namestr.c_str(), cnt++, getpid());
 36             write(pipefd[1], buffer, strlen(buffer));
 37             sleep(1);
 38         }
 39         close(pipefd[1]);
 40         exit(0);
 41     }
 42     //父进程
 43     //3、关闭不需要的fd
 44     close(pipefd[1]);
 45     //4、开始通信
 46     char buffer[1024];
 47     while(true)
 48     {
 49         int n = read(pipefd[0], buffer, sizeof(buffer) - 1);                                                                                                                                                  
 50         if(n > 0)
 51         {
 52             buffer[n] = '\0';
 53             std::cout << "我是父进程,child give me message: " << buffer << std::endl;
 54         }
 55     }
 56     close(pipefd[0]);
 57     return 0;
 58 }

链接: https://gitee.com/kongqizyd/linux-beginner/tree/master/pipe

3、总结

特点

1、单向通信,一种半双工,意思为双方交替着工作;全双工则是双方可以同时工作
2、管道本质是文件,因为文件描述符和文件的生命周期随进程,所以管道的生命周期也随进程。父子进程退出,那么之前关掉的文件描述符又会回到之前的位置
3、父子进程能够通信也是有继承存在于其中的。管道通信通常用于具有“血缘”关系的进程,常用于父子进程。兄弟进程之间也可以通信。pipe打开管道时不需要关心打开了哪个文件,只要得到两个文件描述符就好,因为pipe打开的匿名管道
4、管道通信中,写入的次数和读取的次数不是严格匹配的,可能读了7个但是只读了1次把它们都读取了。读写没有强相关。读取是面向字节流的,读取只看应读的字节数
5、管道具有一定的协同能力,让读和写能按照一定的步骤进行通信----自带同步机制

场景

1、如果我们read读取完了所有的管道数据,对方不写入,读取方只能等待
2、write端写满后(一般是65535/65536,大约是64kb),就不会继续写了,等到读端读取。可以在子进程那里不写sleep,而父进程sleep(10),看实际现象
3、如果关闭了写端,读取完管道数据,再读就会返回0,表明读到了文件结尾
4、写端一直写,读端关闭,那么写入就变得没有意义;操作系统不会维护无意义,低效率,浪费资源的进程,所以进程会直接杀掉这个进程。系统会通过信号来终止进程,SIGPIPE -13关闭进程

3、匿名管道——控制进程

父进程可以通过向子进程写入特定的消息,唤醒子进程,甚至让子进程定向的执行某种任务。父进程可以打开多个管道和子进程连接。父进程对自己创建的管道和进程会先描述再组织。

子进程在创建时会继承父进程的文件描述符,所以第一个父进程会有好多个子进程连接到它,这就混乱了。实际要实现的结构是一对一,一对父子进程间有自己独立的管道,而不受其他进程影响。

链接: https://gitee.com/kongqizyd/linux-beginner/tree/master/ctrlProcess

4、命名管道

匿名管道有局限性,只能用于有血缘关系的进程之间进行通信,要让两个陌生的进程之间通信就需要用到命名管道。

创建命名管道要用到mkfifo命令,括号里就是命名管道参数,fifo意思就是先进先出

在这里插入图片描述

它的文件类型以p开头,说明是一个管道文件。

现在写个命令echo “字符串” >fifo,往这里面写内容,但是光标会停在下一行开头,一直闪烁,这是因为fifo文件只是一个符号,向里面写的东西不会真实存在在磁盘中,只写到管道文件中,我们可以用cat命名读,它默认从显示器读,cat < fifo就会从管道文件读,然后打印到显示器上。即使写一个一直输出内容的代码,也可以另开一个窗口用cat来获取内容。

1、原理

在之前基础IO博客中的硬链接部分写到过引用计数这个东西,命名管道里也会用到引用计数。在磁盘中的一个文件,如果不打开,就待在磁盘里;打开后就会有自己的文件结构体,里面有各项参数,其中就有引用计数;操作者创建进程后,会有文件描述符表等东西,进程可以打开在内存中的文件,此时引用计数就变成了1;如果再开一个进程,打开同样的文件,系统不会在开一个这个文件的结构体,而是这两个进程指向同一个文件结构体,计数变为2,进程一个个消失,计数就从2变为0。但两个进程如何保证打开同一个文件,要想让文件唯一,文件路径+文件名都相同就可以。

2、模拟实现

创建管道文件,让读写端进程分别按照自己的需求打开文件,然后开始通信。

在这里插入图片描述

我们定义两个文件,要形成两个可执行程序需要这样写。

在这里插入图片描述

链接: https://gitee.com/kongqizyd/linux-beginner/tree/master/namepipe

结束。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/444270.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux下SOCKET编程

一、SOCKET编程 1、socket()函数 int socket(int protofamily, int type, int protocol);//返回sockfd返回值sockfd是描述符。 socket函数对应于普通文件的打开操作。普通文件的打开操作返回一个文件描述字&#xff0c;而socket()用于创建一个socket描述符&#xff08;socke…

2. C++使用Thread线程参数传递问题

1. 说明 在子线程函数中进行参数传递&#xff0c;实际上是Thread类的构造函数对传递的参数进行了拷贝&#xff0c;拷贝到线程独立的内存中&#xff0c;及时参数是引用的形式&#xff0c;也可以在新线程中进行访问&#xff0c;如果参数传递时的类型不一致&#xff0c;在线程的上…

Servlet(二)

目录 1.Cookie 和 Session 1.1HttpServletRequest 类中的相关方法 1.HttpSession getSession() 2.Cookie[] getCookies() 1.2HttpServletResponse 类中的相关方法 1.void addCookie(Cookie cookie) 1.3HttpSession 类中的相关方法 1.4Cookie 类中的相关方法 1.5网页登录…

详解Spring Security

目录 1.概述 2.登录 2.1.默认用户 2.2.自定义用户 2.3.加密 2.4.绕过加密 2.5.怎么传递用户信息 2.6.记住我 3.登出 4.使用数据库 4.1.jdbcAuthentication 4.2.userDetailsService 5.自定义处理器 6.更多细粒度的控制 7.原理简述 1.概述 Spring Security是一个…

使用 Kubernetes 运行 non-root .NET 容器

翻译自 Richard Lander 的博客 Rootless 或 non-root Linux 容器一直是 .NET 容器团队最需要的功能。我们最近宣布了所有 .NET 8 容器镜像都可以通过一行代码配置为 non-root 用户。今天的文章将介绍如何使用 Kubernetes 处理 non-root 托管。 您可以尝试使用我们的 non-root…

gateway报 netty堆外内存溢出问题解决io.netty.util.internal.OutOfDirectMemoryError

昨天线上网关突然无法访问。打开日志看到错误信息“io.netty.util.internal.OutOfDirectMemoryError” 堆外内存溢出。。这也没碰到过啊&#xff0c;看来今天准点下班的愿望又落空了。老规矩面向百度编程。先看看网上有没有其他兄弟碰到这个问题。一顿搜索之后发现&#xff0c;…

已解决windows pycocotools安装失败问题 —— 超简单

作者主页&#xff1a;爱笑的男孩。的博客_CSDN博客-深度学习,YOLO,活动领域博主爱笑的男孩。擅长深度学习,YOLO,活动,等方面的知识,爱笑的男孩。关注算法,python,计算机视觉,图像处理,深度学习,pytorch,神经网络,opencv领域.https://blog.csdn.net/Code_and516?typecollect个人…

分库分表与分布式主键生成策略详解--一个无数人踩过却一直被人忽视的深坑

文章目录 一、从分库分表的一个神坑说起二、分布式主键要考虑哪些问题&#xff1f;三、主要的主键生成策略1、数据库策略2、应用单独生成3、第三方服务统一生成4、与第三方结合的segment策略 四、定制雪花算法1、如影随形的时钟回拨问题2、用主键生成策略优化分配工作进程位3、…

萤石“小步快走”,跨进智能家居生态圈

文丨智能相对论 作者丨Kinki 近日&#xff0c;萤石网络&#xff08;下称“萤石”&#xff09;举办了2023春季新品发布会&#xff0c;这是公司上市以来的首个新品发布会&#xff0c;除了拳头产品智能家居摄像机之外&#xff0c;还有智能入户产品、TV Studio等十多款新品&#…

NC65 集团业务参数 GLS01参数值的默认值作用是什么?

NC65 集团业务参数 GLS01参数值的默认值作用是什么&#xff1f; 用在总账系统的所有账簿。如果设置的期间个数大于12&#xff0c;还得要求所查询的账表支持跨年查询&#xff0c;比如科目余额表&#xff0c;不支持跨年&#xff08;注意&#xff1a;这里说的不支持跨年是指余额为…

4.2.1朴素模式匹配算法

什么是字符串的模式匹配&#xff1a; 从这段字符串里面搜索内容&#xff0c;被搜索的字符串我们称之为主串。 也可能匹配不到 主串长度为n&#xff0c;模式串长度为m。 朴素模式匹配算法&#xff1a;将主串中所有长度为m的字串依次与模式串对比&#xff0c;直到找到一个完全匹…

【JavaEE】File、InputStream和OutputStream的使用

1.File 在计算机中目录结构如下&#xff1a; 而File就表示一个目录或者一个普通文件。 File表示目录&#xff1a; File表示普通文件&#xff1a; 我们先来看File的构造方法&#xff1a; 构造器描述File(File parent, String child)根据父目录 孩子文件路径&#xff0c;创…

Linux权限提升—定时任务、环境变量、权限配置不当、数据库等提权

Linux权限提升—定时任务、环境变量、权限配置不当、数据库等提权 1. 前言1.1. 如何找编译好的EXP 2. 定时任务提权2.1. 查看定时任务2.2. 通配符注入提权2.2.1. 创建执行脚本2.2.2. 创建定时任务2.2.3. 查看效果2.2.4. 提权操作2.2.4.1. 切换普通用户2.2.4.2. 执行命令2.2.4.3…

优先、双端队列-我的基础算法刷题之路(八)

本篇博客旨在整理记录自已对优先队列、双端队列的一些总结&#xff0c;以及刷题的解题思路&#xff0c;同时希望可给小伙伴一些帮助。本人也是算法小白&#xff0c;水平有限&#xff0c;如果文章中有什么错误之处&#xff0c;希望小伙伴们可以在评论区指出来&#xff0c;共勉 &…

Netty 源码解析(下)

接上一篇博客 Netty 源码解析&#xff08;上&#xff09;继续分析 上一篇博客中已经分析了绝大部分 ChannelFuture cf bootstrap.bind(9000).sync(); 这一行代码&#xff0c;当这一行代码运行完时&#xff0c;Netty服务端就已经启动好了&#xff0c;接下来就是接收链接&#x…

Spring Security OAuth2.0(二)-----简化模式/密码模式/客户端模式/刷新 token

简化模式 代码示例 修改authorization_server授权服务模块 新增“implicit” 和修改回调地址为本次地址 修改第三方应用项目搭建新页面模拟 新建implicit.jsp <% page contentType"text/html;charsetUTF-8" language"java" isELIgnored"fals…

C++入门篇(二)

目录 一、引用1.1 什么是引用&#xff1f;1.2 引用的特性1.3 常引用1.4 引用的使用场景1.5 传值和传引用效率比较1.5.1 传值和传引用做参数的性能对比1.5.2 传值和传引用做返回值的性能对比 1.6 引用和指针之间的区别 二、内联函数2.1 什么是内联函数&#xff1f;2.2 内联函数的…

知识变现海哥|研究了100个项目,这个才是人生逆袭首选

&#xff08;本文源自公号跟海哥学知识变现&#xff0c;移步公号与100万知识变现/知识付费创业者&#xff0c;一起学知识变现知识付费干货&#xff0c;回‘领书’获取3本电子书&#xff1a;【知识付费秘籍】【知识创业者成长手册】【100个知识付费成功案例】) 经常有人问海哥&a…

什么是中断向量表?作用是什么?为什么需要偏移?

一、定义与特点 定义&#xff1a;中断向量表(interrupt vector table)包含中断服务程序地址的特定内存区域&#xff0c;这些服务程序是处理外部硬件中断请求的代码。 特点&#xff1a;这些中断服务程序(函数)在中断向量表中的位置是由半导体厂商定好的&#xff0c;当某个中断…

ESP32-C2开发板 Homekit烧录教程

准备 1.1硬件ESP32 C2开发板&#xff0c;如图1-1所示 图1-1 ESP32 C2开发板 1.2软件 CozyLife APP可以在各大应用市场搜索下载&#xff0c;也可以扫描二维码下载如图1-2所示 HomeKit flash download tool 烧录工具 esp32c2 homkit演示固件 烧录教程 打开flash_download_to…