零基础入门进程间通信:task 1(匿名管道与vscode使用)

目录

引言

VSCODE使用

进程间通信正题

基础背景

进程间通信分类

匿名管道

理解匿名管道

代码实现

匿名管道的特性

管道的四种情况

应用场景


引言

在当今的计算机技术领域,操作系统作为计算机系统的核心组件,承担着资源管理、任务调度和进程管理等重要职责。Linux作为一种开源、高性能、稳定的操作系统,广泛应用于服务器、嵌入式设备和个人电脑中。在Linux系统中,进程是资源分配和调度的基本单位,而进程间通信(Inter-Process Communication,IPC)则是确保多个进程能够协同工作、共享数据的关键技术。

本系列文章将通过task1-4来完成进程间通信的学习。

task 1将着重介绍:1.VScode远端连接linux云服务器 2.匿名管道通信

VSCODE使用

将VScode与linux远端的机器进行连接。

首先我们需要下载remote插件,F1找到remote添加远端主机指令。

输入用户名和远端主机的信息:ssh XXX@12345678

我们可以选择记住这个主机。

完成之后自己的用户内部有一个文件。

这个文件内部就添加了主机信息了(可以进行删除)

这样就提示连接上了远端。

需要注意的是,我们写完代码必须Ctrl + S保存才能保存文件。

从此我们就不需要用vim了,用vscode就可以进行代码编写

进程间通信正题

基础背景

进程通信的本质是:让不同的进程看到同一份资源。

这个资源一般是特定的内存空间,起这个资源一般是OS提供。

system V一般本机通信

posix一般网络通信

system V的通信标准给出了三个:消息队列、共享内存、信号量。

当然还有基于文件的通信:管道

进程间通信分类

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

匿名管道

什么是管道
管道是 Unix 中最古老的进程间通信的形式。
我们把从一个进程连接到另一个进程的一个数据流称为一个 管道 ”。

理解匿名管道

父进程用wr的形式分别open打开一个文件

fork出子进程之后,子进程会继承父进程文件描述符表files_struct。指向同样的file结构

父子关闭不需要的接口,就可以实现资源的互联。

进程就像是用户,关闭打开某个文件,对文件产生的影响都是通过OS进行的。file结构内部存在计数器,关闭文件会造成计数器--。

匿名管道只能用于亲戚进程通信:父子可以、兄弟可以、孙子爷爷可以(只要有一样的files_struct就可以)。

fork 来共享管道原理

站在文件描述符角度 - 深度理解管道
站在内核角度 - 管道本质

open打开的是磁盘的文件,内存的文件怎么办?

pipe用于打开在内存级别的一个文件,这个文件也存在缓冲区……

创建一个管道pipe(用读和写的形式打开一个文件两次)。

大部分系统调用,用于判断是否成功,成功一般返回0,否则-1.

传参提醒你,传入一个两个元素组成的int数组,这是一个输出型参数

pipefd[0]是读文件打开方式的fd

pipe[1]是写方式打开文件的fd

代码实现

实现一个子进程写,父进程读的逻辑代码


int main() 
{
    int pipefd[2] = {0};
    int ret = pipe(pipefd);     //创建内存管道文件,0是read端,1是write端。虽然fd不同,但是是同一个文件。
    if (ret < 0) 
    {
        cout << "Failed to create pipe" << endl;
        return -1;
    }

    // cout << "pipefd[0] = " << pipefd[0] << ", pipefd[1] = " << pipefd[1] << endl;

    pid_t id = fork();
    
    if (id < 0) 
    {
        cout << "Failed to fork" << endl;
        return -1;
    }

    //子进程写,父进程读
    if (id == 0)
    {
        // child process
        close(pipefd[0]);
        //ipc code 
        Writer(pipefd[1]);      //不断写

        close(pipefd[1]);
        exit(0);
    }

    // parent process
    close(pipefd[1]);
    //ipc code 

     //虽然子进程将pipepid[0]关闭了,但是只会让file结构--,父进程还是可以对pipefd[0]进行读操作的。
    Reader(pipefd[0]);      
    pid_t retid = waitpid(id, nullptr, 0);
    if (retid < 0)  
    {
        cout << "Failed to wait child process" << endl; 
        return 3;
    }
    close(pipefd[0]);

    return 0;
}    

写入缓冲区


//child process
void Writer(int Wfd) 
{   
    string str = "Hello, im child process!";
    pid_t pid = getpid();
    int number = 0;

    char buffer[1024] = {0};

    while (true)
    {
        //构建发送字符串
        buffer[0] = '\0';   //清空缓冲区,告诉读者,这是一个字符串
        snprintf(buffer, sizeof(buffer), "%s pid = %d, number = %d\n", str.c_str(), pid, number++);
        // cout << buffer << endl;
        sleep(10);

        //发送字符串给父进程(只要你是一个文件,存在fd,就可以用write向文件写入内容)
        write(Wfd, buffer, strlen(buffer));     //write是写入到了文件缓冲区

    }
    

}

snprintf可以将数据格式化的写道字符串中

从缓冲区读取


//parent process
void Reader(int Rfd) 
{
    char buffer[1024] = {0};
    while (true)
    {
        buffer[0] = '\0';   //清空缓冲区,告诉读者,这是一个字符串   

        //从文件中读取字符串
        ssize_t n = read(Rfd, buffer, sizeof(buffer));   //sizeof(buffer) != strlen(buffer)
        if (n > 0)   //n是读取的字节数
        {
            buffer[n] = 0;   //字符串末尾加上'\0'
            cout << "Received message: " << buffer << endl;
        }
    }
    
}

总结

核心逻辑就是父进程用pipe打开一个内存级别的文件两次

父进程创建子进程

子进程调用W函数,父进程调用R函数

W函数就是借助pipefd[1]向文件缓冲区写入(write)

R函数就是借助pipefd[0]从缓冲区读取(read)

父进程等待子进程

易错解析

每次打开一个文件都会产生一个file结构,同时获得一个file结构对应的fd。

读方式打开,获得读方式的fd

写方式打开,获得写方式的fd

一个进程可以用不同的方式打开一个文件多次。

我们不可以通过建立全局字符串的方式去进行通信,因为子进程在修改字符串时,会发生写时拷贝。

所有进行进程通信的时候,所占用的区域属于OS管理,而不是某个进程。

匿名管道的特性

1.只有亲戚之间可以通信

2.管道只能单向通信

3.父子进程协同、互斥(限定资源的抢占特性)、同步通信的特性

eg:子进程休眠10s才写入一次,那父进程也别着急读,会等待一下进程(并不会读取空的管道,因为没有打印Received message:,说明直接没有读)

4.管道面向字节流

不管你写的是什么,在r端认为都是一个个字节,只负责读。所谓的格式区分,不是r端该干的活,这种特性就是字节流。

5.管道基于文件,而文件被打开的生命周期基于进程,所以进程结束,管道关闭。

6.管道是有固定大小的,在不同的内核中,可能有差别

7.管道的原子性

原子性:小于pipe_buf,就是原子的。保证读写的连贯性 4kb

管道的四种情况

读写端正常,管道为空,读端阻塞

读写端正常,管道满了,写段阻塞

写端关闭,read会读取到EOF,返回0,不会阻塞

读端关闭,写端继续写入时,OS就要(通过信号)杀掉写进程

写端关闭特指的是:一定要现有写端被打开的现象,才能说是写端被关闭。如果写端都哦没有被打开,就不存在关闭一说

在命名管道(FIFO)的情况下,"写端关闭"这个说法确实指的是写端曾经被打开,并且随后被关闭。以下是详细解释:

打开写端:这意味着至少有一个进程通过 open 系统调用以写模式(O_WRONLY)打开了管道的写端,从而能够向管道写入数据。

关闭写端:这发生在进程完成写入操作后,通过 close 系统调用关闭了写端。关闭写端意味着该进程不再向管道写入数据,但如果有其他进程已经打开了写端,它们仍然可以写入。

写端未被打开:如果没有任何进程以写模式打开管道的写端,那么我们就不能说写端被关闭,因为关闭是一个状态改变,需要先有一个打开的状态。

因此,如果没有进程曾经打开过写端,那么说“写端被关闭”是不准确的。在这种情况下,更准确的说法是“写端尚未被打开”或“没有进程打开写端”。

当读端进程尝试从管道读取数据时,如果写端尚未被任何进程打开,那么读操作会阻塞,等待写端的打开和数据的写入。只有当至少一个进程打开了写端并写入数据后,读端进程的读操作才会解除阻塞并读取数据。如果所有写端都被关闭,并且没有数据留在管道中,那么读操作会返回0,表示到达了文件末尾。

应用场景

在bash中输入的|管道符号就是一种匿名管道。

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

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

相关文章

Vue 3 的 全局状态管理

1.思路梳理 工厂仓拣货信息&#xff1a;Factory Picking Info (FPI)工厂仓调度信息&#xff1a;Factory Scheduling Info (FSI)DC 收货信息&#xff1a;DC Receiving Info (DCRI)上架信息&#xff1a;Shelving Info (SI)盘点信息&#xff1a;Inventory Count Info (ICI)移位信…

Win系统通过命令行查看笔记本电池损耗/寿命/健康

在 Windows 10/11 系统中&#xff0c;可以通过指令查看笔记本电池的寿命情况&#xff0c;方法如下&#xff1a; 0&#xff0c;打开cmd/终端 键盘快捷键&#xff1a;Win R&#xff0c;然后输入cmd&#xff0c;点击【确定】 1&#xff0c;执行命令 在命令行中输入下面指令并按…

【DM系列】DM 集成 JDBC 开发指南

前言 数据库访问是数据库应用系统中非常重要的组成部分&#xff0c;DM 作为一个通用数据库管理系统&#xff0c;提供了多种数据库访问接口&#xff0c;包括 ODBC、JDBC、DPI 等方式。本开发指南详细介绍了 DM 的各种访问接口、相应开发环境的配置、以及一些开发用例。本指南的主…

【客观理性深入讨论国产中间件及数据库-科创基础软件】

随着国产化的进程&#xff0c;越来越多的国企央企开始要求软件产品匹配过程化的要求&#xff0c; 最近有一家银行保险的科技公司对行为验证码产品就要求匹配国产中间件&#xff0c; 于是开始了解国产中间件都有哪些厂家 一&#xff1a;国产中间件主要产品及厂商 1 东方通&…

python opencv3

三、图像预处理2 1、图像滤波 为图像滤波通过滤波器得到另一个图像。也就是加深图像之间的间隙&#xff0c;增强视觉效果&#xff1b;也可以模糊化间隙&#xff0c;造成图像的噪点被抹平。 2、卷积核 在深度学习中&#xff0c;卷积核越大&#xff0c;看到的信息越多&#xff0…

数据库管理-第258期 23ai:Oracle Data Redaction(20241104)

数据库管理258期 2024-11-04 数据库管理-第258期 23ai&#xff1a;Oracle Data Redaction&#xff08;20241104&#xff09;1 简介2 应用场景与有点3 多租户环境4 特性与能力4.1 全数据编校4.2 部分编校4.3 正则表达式编校4.4 随机编校4.5 空值编校4.6 无编校4.7 不同数据类型上…

Kettle——CSV文件转换成excel文件输出

1.点击—文件—新建—转换 拖入两个组件&#xff1a; 按shift&#xff0b;鼠标左击建立连接&#xff0c;并点击主输出步骤&#xff0c; 点击CSV文件输入&#xff0c;选择浏览的csv文件&#xff0c;然后点击确定 同样&#xff0c;Excel也同上&#xff0c;只是要删除这个xls 并…

【数据集】【YOLO】【目标检测】火情、烟雾、火灾检测数据集 9848 张,YOLO火灾检测算法实战训练教程!

数据集介绍 【数据集】火情、烟火、火灾检测数据集 9848 张&#xff0c;目标检测&#xff0c;包含YOLO/VOC格式标注。 数据集中包含2种分类&#xff1a;{0: Fire, 1: Smoke}&#xff0c;分别是‘火焰’和‘烟雾’。 数据集来自国内外图片网站和视频截图&#xff1b; 可用于…

Python酷库之旅-第三方库Pandas(202)

目录 一、用法精讲 941、pandas.CategoricalIndex.set_categories方法 941-1、语法 941-2、参数 941-3、功能 941-4、返回值 941-5、说明 941-6、用法 941-6-1、数据准备 941-6-2、代码示例 941-6-3、结果输出 942、pandas.CategoricalIndex.as_ordered方法 942-1…

docker 拉取MySQL8.0镜像以及安装

目录 一、docker安装MySQL镜像 搜索images 拉取MySQL镜像 二、数据挂载 在/root/mysql/conf中创建 *.cnf 文件 创建容器,将数据,日志,配置文件映射到本机 检查MySQL是否启动成功&#xff1a; 三、DBeaver数据库连接 问题一、Public Key Retrieval is not allowed 问题…

Java多线程详解⑤(全程干货!!!)线程安全问题 || 锁 || synchronized

这里是Themberfue 在上一节的最后&#xff0c;我们讨论两个线程同时对一个变量累加所产生的现象 在这一节中&#xff0c;我们将更加详细地解释这个现象背后发生的原因以及该如何解决这样类似的现象 线程安全问题 public class Demo15 {private static int count 0;public …

如何使用RabbitMQ和Python实现广播消息

使用 RabbitMQ 和 Python 实现广播消息的过程涉及设置一个消息队列和多个消费者&#xff0c;以便接收相同的消息。RabbitMQ 的 “fanout” 交换机允许你将消息广播到所有绑定的队列。以下是如何实现这一过程的详细步骤。 1、问题背景 在将系统从Morbid迁移到RabbitMQ时&#x…

【RabbitMQ】04-发送者可靠性

1. 生产者重试机制 spring:rabbitmq:connection-timeout: 1s # 设置MQ的连接超时时间template:retry:enabled: true # 开启超时重试机制initial-interval: 1000ms # 失败后的初始等待时间multiplier: 1 # 失败后下次的等待时长倍数&#xff0c;下次等待时长 initial-interval…

java的类加载机制的学习

一、类加载的过程 一个类被加载到虚拟机内存中开始&#xff0c;到卸载出虚拟机内存为止&#xff0c;整个生命周期分为七个阶段&#xff0c;分别是加载、验证、准备、解析、初始化、使用和卸载。其中验证、准备和解析这三个阶段统称为连接。 除去使用和卸载&#xff0c;就是Ja…

uni-app跨域set-cookie

set-cookie的值是作为一个权限控制的 首先&#xff0c;无论什么接口都会返回一个set-cookie&#xff0c;但未登录时&#xff0c;set-cookie是没有任何权限的 其次&#xff0c;登录接口请求时会修改set-cookie&#xff0c;并且在后续其他接口发起请求时&#xff0c;会在请求头…

让智能体—“正念365”陪你一起“养心”

佛学的“八正道”中&#xff0c;笔者个人观点&#xff0c;“正念”是最适合当代人低门槛练习的一个&#xff0c;因为不需要阅读大量的知识来理解概念&#xff0c;只需要保持对当下的觉察&#xff0c;发现分心了&#xff0c;就不带评价的把注意力拉回到当前的事情上就好。就是佛…

浅析Android Handler机制实现原理

0. 背景描述 Android系统出于对简单、高效的考虑&#xff0c;在设计UI体系时采用了单线程模型&#xff0c;即不会在多个线程中对同一个UI界面执行操作。简单是指单线程模型可以不用考虑和处理在多线程环境下操作UI带来的线程安全问题&#xff0c;高效是指单线程模型下无需通过…

vue 3:监听器

目录 1. 基本概念 2. 侦听数据源类型 1. 监听getter函数 2. 监听 ref 或 reactive 的引用 3. 多个来源组成的数组 4. 避免直接传递值&#xff01;&#xff01;&#xff01; 3. 深层侦听器 4. 立即回调的侦听器 5. 一次性侦听器 6. watchEffect() 7. 暂停、恢复和停止…

沉浸式学习新体验:3D虚拟展厅如何重塑教育格局!

3D虚拟展厅对于教育行业产生了深远的影响&#xff0c;主要体现在以下几个方面&#xff1a; 一、创新教学方式 3D虚拟展厅利用三维技术构建的虚拟展示空间&#xff0c;为教育行业带来了一种全新的教学方式。传统的教学方式往往局限于书本和课堂&#xff0c;而3D虚拟展厅则能够…

【Kafka】Windows+KRaft部署指南

【Kafka】WindowsKRaft部署指南 摘要本地环境说明官网快速开始修改config/kraft/server.properties初始化数据存储目录启动 测试创建topic创建生产者创建消费者 FAQ输入行太长。命令语法不正确。问题描述解决方案 参考资料 摘要 Kafka是一种高吞吐量的分布式发布订阅消息系统&…