Linux系统---进程间通信与管道入门

顾得泉:个人主页

个人专栏:《Linux操作系统》 《C++从入门到精通》  《LeedCode刷题》

键盘敲烂,年薪百万!


一、进程间通信

1.进程间通信的目的

     1.数据传输:一个进程需要把他的数据传给另外一个进程。

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

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

     4.进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。

2.进程间通信发展

       最早的进程间通信方式是使用操作系统提供的共享内存和消息队列机制。共享内存允许多个进程将同一段内存映射到它们自己的地址空间,从而实现数据共享;消息队列则允许进程通过发送和接收消息来进行通信。

       随着网络技术的发展,进程间通信也逐渐向网络通信发展。网络通信使得不同计算机上的进程能够进行跨机器的通信和协作。常见的网络通信方式包括套接字(socket)、远程过程调用(RPC)和消息传递接口(MPI)等。

       近年来,随着多核处理器和分布式计算的普及,进程间通信的需求也越来越高。为了提高通信效率和方便编程,各种新的进程间通信技术应运而生。例如,管道(Pipe)和FIFO允许两个相关进程之间进行通信;信号量(Semaphore)和互斥锁(Mutex)等同步机制可以确保多个进程之间的正确协作;套接字和远程过程调用等技术允许分布在不同计算机上的进程进行通信。

3.进程间通信分类

管道

     1.匿名管道pipe

     2.命名管道

System V IPC

     1.System V 消息队列

     2.System V 共享内存

     3.System V 信号量

POSIX IPC

     1.消息列队

     2.共享内存

     3.信号量

     4.互斥量

     5.条件变量

     6.读写锁


二、管道

1.管道简介

       在Linux中,管道(pipeline)是一种机制,用于将一个命令的输出作为另一个命令的输入。通过使用管道,可以将多个命令组合在一起,以便实现更复杂的操作。

       在命令行中,使用竖线符号( | )来表示管道。

2.匿名管道

#include <unistd.h>

功能:创建一无名管道

原型

int pipe(int fd[2]);

参数

fd:文件描述符数组,其中fd[0]表示读端, fd[1]表示写端

返回值:成功返回0,失败返回错误代码

实例代码:

       从键盘读取数据,写入管道,读取管道,写到屏幕

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main( void )
{
    int fds[2];
    char buf[100];
    int len;
    if ( pipe(fds) == -1 )
    perror("make pipe"),exit(1);
    // read from stdin
    while ( fgets(buf, 100, stdin) ) 
    {
        len = strlen(buf);
        // write into pipe
        if ( write(fds[1], buf, len) != len ) 
        {
            perror("write to pipe");
            break;
        }
        memset(buf, 0x00, sizeof(buf));
        
        // read from pipe
        if ( (len=read(fds[0], buf, 100)) == -1 ) 
        {
            perror("read from pipe");
            break;
        }
        // write to stdout
        if ( write(1, buf, len) != len ) 
        {
            perror("write to stdout");
            break;
        }
    }
}

3.用fork来共享管道原理

       fork系统调用会在父进程中创建一个新的子进程,这个子进程与父进程几乎完全相同,包括代码段、数据段和堆栈段。这意味着子进程可以继承父进程的打开文件描述符等资源。

       在使用fork创建子进程后,父进程和子进程可以通过管道来进行通信。管道是一种特殊的文件,它能够连接一个进程的输出和另一个进程的输入。在Linux中,管道可以通过pipe系统调用来创建。

       当父进程创建管道后,它可以使用fork来创建子进程。接下来,父进程可以关闭管道的读端,子进程可以关闭管道的写端。这样,父进程就可以将数据写入管道的写端,子进程可以从管道的读端读取数据。

具体操作如下:

     1.父进程使用pipe系统调用创建一个管道。

     2.父进程使用fork系统调用创建子进程。

     3.子进程关闭管道的写端。

     4.父进程关闭管道的读端。

     5.父进程将要传输的数据写入管道的写端。

     6.子进程从管道的读端读取数据。

       父进程可以通过管道将数据传输给子进程,子进程可以通过管道接收父进程传输的数据。这样,父进程和子进程就可以进行进程间通信了。

       需要注意的是,管道的容量是有限的,如果管道被写满后继续写入数据,写入操作会被阻塞,直到有数据被读取出来为止。同样,如果管道为空时读取数据,读取操作也会被阻塞,直到有数据被写入为止。因此,在使用共享管道进行进程间通信时,需要合理控制数据的读写操作,以避免阻塞问题的发生。


三、深度理解管道

1.文件描述符角度

1.父进程创建管道

2.父进程fork出子进程

3.父进程关闭fd[0],子进程关闭fd[1]

2.内核角度-内核本质

       管道的实现机制:内核中的管道是通过一对文件描述符来实现的。一个文件描述符用于读取管道数据,另一个文件描述符用于写入管道数据。内核维护着一个缓冲区,用于存放从写入端写入的数据,并且从读取端读取的数据会从缓冲区中删除。

       管道的数据传输:管道是一种半双工的通信方式,数据只能单向流动。当写入端写入数据时,数据会被放入缓冲区中,直到被读取端读取。如果缓冲区已满,则写入操作会被阻塞,直到缓冲区有空闲空间。同样,如果缓冲区为空,则读取操作会被阻塞,直到缓冲区有数据。

       管道的进程同步:当多个进程使用管道通信时,可能会出现进程同步的问题。例如,如果写入端连续写入数据,而读取端没有及时读取,那么缓冲区可能会溢出。为了解决这个问题,内核提供了一些同步机制,例如管道的阻塞和非阻塞模式、管道的读取和写入端都关闭时的特殊情况等。

       管道的文件描述符操作:在内核中,文件描述符是一种操作系统提供给用户空间的接口。通过文件描述符的操作,可以实现对管道的读取和写入。对于读取操作,可以使用read系统调用从管道中读取数据;对于写入操作,可以使用write系统调用向管道中写入数据。


结语:关于理解Linux系统下的进程间通信与管道基础的分享到这里就结束了,没有进行展示的操作大家可以自行练习,希望本篇文章的分享会对大家的学习带来些许帮助,如果大家有什么问题,欢迎大家在评论区留言~~~ 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

el-table实现表格内部横向拖拽效果

2024.4.2今天我学习了如何对el-table表格组件实现内部横向拖拽的效果&#xff0c;效果&#xff1a; 代码如下&#xff1a; 一、创建utils/底下文件 const crosswise_drag_table function (Vue){// 全局添加table左右拖动效果的指令Vue.directive(tableMove, {bind: function…

IMU参数辨识及标定

IMU参数辨识及标定 一、标定参数分析 标定的本质是参数辨识。首先明确哪些参数可辨识&#xff0c;其次弄清怎样辨识。 参数包括陀螺仪和加速度计各自的零偏、标度因数、安装误差。 IMU需要标定的参数主要是确定性误差和随机误差&#xff0c;确定性误差主要标定bias&#xff0…

Python 之 Flask 框架学习

毕业那会使用过这个轻量级的框架&#xff0c;最近再来回看一下&#xff0c;依赖相关的就不多说了&#xff0c;直接从例子开始。下面示例中的 html 模板&#xff0c;千万记得要放到 templates 目录下。 Flask基础示例 hello world from flask import Flask, jsonify, url_fora…

STM32H5 读取温度传感器校准值时进 HardFault 的原因分析

1.前言 有客户反馈&#xff0c;在使用 STM32H5 读取温度传感器校准值地址时&#xff0c;会进入 HardFault&#xff0c;而在其他系列芯片中读取这个参数时并没有此现象。在 NUCLEO-H563ZI 开发板上去复现此问题&#xff0c;发现只有开启 ICACHE 后才会复现&#xff0c;初步验证…

图像处理与视觉感知---期末复习重点(6)

文章目录 一、图像分割二、间断检测2.1 概述2.2 点检测2.3 线检测2.4 边缘检测 三、边缘连接3.1 概述3.2 Hough变换3.3 例子3.4 Hough变换的具体步骤3.5 Hough变换的法线表示形式3.6 Hough变换的扩展 四、阈值处理4.1 概述4.2 计算基本全局阈值算法4.3 自适应阈值 五、基于区域…

ElementUI 表格横向滚动条时滚动到指定位置

ElementUI 表格横向滚动条时滚动到指定位置 getColumnOffset(columnProp) {this.$nextTick(() > {const table this.$refs.tableRef.$refs.multipleTable;const columns table.columns;const column columns.find((col) > col.property columnProp);if (column) {// …

Flume学习笔记

视频地址:https://www.bilibili.com/video/BV1wf4y1G7EQ/ 定义 Flume是一个高可用的、高可靠的、分布式的海量日志采集、聚合和传输的系统。 Flume高最要的作用就是实时读取服务器本地磁盘的数据,将数据写入HDFS。 官网:https://flume.apache.org/releases/content/1.9.0/…

Python PDF页面设置 -- 旋转页面、调整页面顺序

在将纸质文档扫描成PDF电子文档时&#xff0c;有时可能会出现页面方向翻转或者页面顺序混乱的情况。为了确保更好地浏览和查看PDF文件&#xff0c;本文将分享一个使用Python来旋转PDF页面或者调整PDF页面顺序的解决方案。 目录 使用Python旋转PDF页面 使用Python调整PDF页面…

【Redis 知识储备】单机架构 -- 分布系统的演进(1)

单机架构 1. 概念2. 单机架构的优点3. 单机架构的问题4. 单机架构问题的解决思路 1. 概念 单机架构, 只有一台服务器, 这个服务器负责所有的工作 初期&#xff0c;我们需要利⽤我们精⼲的技术团队&#xff0c;快速将业务系统投⼊市场进⾏检验&#xff0c;并且可以迅速响应变化…

【攻防世界】warmup (代码审计)

进入题目环境&#xff0c;只有一个表情&#xff1a; ctrl u 查看源代码&#xff1a; 源代码提示我们访问 /source.php。访问结果如下&#xff1a; 我们进行代码审计&#xff0c;发现解题的关键点 include &_REQUEST[file]。但是题目使用了白名单进行了过滤。我们发现白名单…

Redis底层数据库之SDS

高速的存储介质&#xff1a;内存优秀的底层数据结构高效的IO模型高效的线程模型 1. 动态字符串SDS Redis中保存的Key是字符串&#xff0c;value往往是字符串或者字符串的集合。可见字符串是redis中最常用的一种数据结构。 C语言种字符串存在的一些问题&#xff1a; 获取字符…

web-AOP

AOP基础 AOP进阶 通知顺序和类型 切入点表达式 连接点

腾讯云(CVM)托管进行权限维持

前言 刚好看到一个师傅分享了一个阿里云ECS实战攻防&#xff0c;然后想到了同样利用腾讯云CVM的托管亦可实现在实战攻防中的权限维持。 简介 腾讯云自动化助手&#xff08;TencentCloud Automation Tools&#xff0c;TAT&#xff09;是一个原生运维部署工具&#xff0c;它可…

链表的极致——带头双向循环链表

​ 文章目录 双向带头循环链表简介&#xff1a;双向&#xff1a;带头&#xff1a;特点&#xff1a;链表带头节点的好处&#xff1a; 循环&#xff1a;特点&#xff1a;循环的好处&#xff1a; 双向带头循环链表的接口函数实现准备工作&#xff1a; 初始化链表&#xff08;头结…

在flutter中添加video_player【视频播放插件】

添加插件依赖 dependencies:video_player: ^2.8.3插件的用途 在Flutter框架中&#xff0c;video_player 插件是一个专门用于播放视频的插件。它允许开发者在Flutter应用中嵌入视频播放器&#xff0c;并提供了一系列功能来控制和定制视频播放体验。这个插件对于需要在应用中展…

HarmonyOS 应用开发之创建自定义组件

在ArkUI中&#xff0c;UI显示的内容均为组件&#xff0c;由框架直接提供的称为系统组件&#xff0c;由开发者定义的称为自定义组件。在进行 UI 界面开发时&#xff0c;通常不是简单的将系统组件进行组合使用&#xff0c;而是需要考虑代码可复用性、业务逻辑与UI分离&#xff0c…

练习 17 Web [极客大挑战 2019]PHP

常见的网站源码备份文件名和后缀&#xff0c;反序列化攻击 unserialize()&#xff1a;wakeup绕过&#xff0c;private类以及属性序列化后的%00修改 开靶机 提到”备份“ 那看看有没有backup.php啥的 如果网站存在备份文件&#xff0c;常见的备份文件后缀名有&#xff1a;“.gi…

系统IO函数接口

目录 前言 一. man手册 1.1 man手册如何查询 1.2 man手册基础 二.系统IO函数接口 三.open打开文件夹 3.1 例1 open打开文件 3.2 open打开文件代码 3.3 例2 创建文件 四.write写文件 4.1 write写文件 五. read读文件 5.1 read读文件与偏移 5.2 偏移细节 5.3 read读文件代码 六.复…

vscode 重命名很慢或失败 vscode renames are slow

网上问题&#xff0c; 插件问题&#xff08;我遇见的排除&#xff0c;不是&#xff09;被其他程序占用问题&#xff0c;&#xff08;我这边是这个&#xff09; 解决方案&#xff1a; 打开【资源管理器】&#xff0c;使用火绒 或其他软件&#xff0c;查看文件夹 or 文件 被哪个…

集合的学习

为什么要有集合&#xff1a;集合会自动扩容 集合不能存基本数据类型&#xff08;基本数据类型是存放真实的值&#xff0c;而引用数据类型是存放一个地址&#xff0c;这个地址存放在栈区&#xff0c;地址所指向的内容存放在堆区&#xff09; 数组和集合的对比&#xff1a; 集…