零基础入门进程间通信: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 processclose(pipefd[0]);//ipc code Writer(pipefd[1]);      //不断写close(pipefd[1]);exit(0);}// parent processclose(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中输入的|管道符号就是一种匿名管道。

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

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

相关文章

#渗透测试#SRC漏洞挖掘#Python自动化脚本的编写04之通过面向对象编程学生管理信息系统01

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

【销帮帮-注册_登录安全分析报告-试用页面存在安全隐患】

联通支付注册/登录安全分析报告 前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨…

微信小程序——01开发前的准备和开发工具

文章目录 一、开发前的准备1注册小程序账号2安装开发者工具 一、开发前的准备 开发前需要进行以下准备&#xff1a; 1 注册小程序账号2激活邮箱3 信息登记4 登录小程序管理后台5完善小程序信息6绑定开发者 1注册小程序账号 第1步&#xff1a;首先打开“微信公众平台” https:…

文心一言 VS 讯飞星火 VS chatgpt (388)-- 算法导论24.5 8题

八、设 G ( V , E ) G(V,E) G(V,E) 为一个带权重的有向图&#xff0c;且包含一个可以从源结点 s s s 到达的权重为负值的环路。请说明如何构造一个 G G G 的边的松弛操作的无限序列&#xff0c;使得每一步松弛操作都能对某一个最短路径估计值进行更新。如果要写代码&#x…

鸿蒙UI开发——自定义UI绘制帧率

1、概 述 随着设备屏幕的不断演进&#xff0c;当前主流设备采用LTPO屏幕&#xff08;可变刷新率屏幕&#xff09;&#xff0c;此类屏幕支持在多个档位之间切换屏幕帧率。 对于快速变化的内容&#xff0c;如射击游戏&#xff0c;交互动画等&#xff0c;显示帧率越高&#xff0…

计算机毕业设计 | SpringBoot慈善公益平台 爱心互助活动发布管理系统(附源码)

1&#xff0c;项目介绍 爱慈善公益平台&#xff08;love-charity&#xff09;是一个基于 SpringBoot 开发的标准 Java Web 项目。整体页面非常的简约大气&#xff0c;项目的完整度较高&#xff0c;是一个偏向公益论坛的系统。非常适合刚刚接触学习 SpringBoot 的技术小白学习&…

在 AMD GPU 上使用 AI2 的 OLMo 模型进行推理

Inferencing with AI2’s OLMo model on AMD GPU — ROCm Blogs 2024 年 4 月 17 日&#xff0c;作者&#xff1a;Douglas Jia. 在这篇博客中&#xff0c;我们将向您展示如何在 AMD GPU 上使用 AI2 的 OLMo 模型生成文本。 简介 由艾伦人工智能研究所&#xff08;Allen Instit…

工作流初始错误 泛微提交流程提示_泛微协同办公平台E-cology8.0版本后台维护手册(11)–系统参数设置

工作流初始错误 泛微提交流程提示_泛微协同办公平台E-cology8.0版本后台维护手册(11)–系统参数设置...-CSDN博客 工作流初始错误 泛微提交流程提示_泛微OA 工作流WebService接口使用说明 工作流初始错误 泛微提交流程提示_泛微OA 工作流WebService接口使用说明-CSDN博客 工作…

C++数学

前言 C算法与数据结构 打开打包代码的方法兼述单元测试 数论&#xff1a;质数、最大公约数、菲蜀定理 组合数学汇总 计算几何 博弈论 曼哈顿距离与切比雪夫距离 红线是哈曼顿距离&#xff0c;绿线是切比雪夫距离。 二维曼哈顿距离转切比雪夫距离 曼哈顿距离&#xff1a;|…

前深度学习时代-经典的推荐算法

参考自《深度学习推荐系统》—— 王喆&#xff0c;用于学习记录。 1.协同过滤 “协同过滤”就是协同大家的反馈、评价和意见一起对海量的信息进行过滤&#xff0c;从中筛选出目标用户可能感兴趣的信息的推荐过程。 基于用户相似度进行推荐的协同过滤算法 UserCF 用户相似度…

10 Oracle Data Guard:打造高可用性与灾难恢复解决方案,确保业务连续性

文章目录 10 Oracle Data Guard&#xff1a;打造高可用性与灾难恢复解决方案&#xff0c;确保业务连续性一、Data Guard基本概念二、Data Guard技术架构三、配置Oracle Data Guard的步骤3.1 准备主数据库和备用数据库3.2 配置Redo日志传输服务3.3 配置Data Guard Broker3.4 启动…

计算机网络综合题

IP数据报的划分 CRC差错检测 冗余码的计算 因此&#xff0c;余数是1110&#xff0c;传输的数为11010110111110。在传输过程中最后两位变成o&#xff0c;接收端能够发现&#xff0c;因为11010110111110除以10011余数不为0。 子网划分 暴力求解法 &#xff08;定长子网划分大量…

计算机课程管理:Spring Boot与工程认证的协同

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

Java | Leetcode Java题解之第557题反转字符串中的单词III

题目&#xff1a; 题解&#xff1a; class Solution {public String reverseWords(String s) {StringBuffer ret new StringBuffer();int length s.length();int i 0;while (i < length) {int start i;while (i < length && s.charAt(i) ! ) {i;}for (int …

C++ | Leetcode C++题解之第556题下一个更大元素III

题目&#xff1a; 题解&#xff1a; class Solution { public:int nextGreaterElement(int n) {int x n, cnt 1;for (; x > 10 && x / 10 % 10 > x % 10; x / 10) {cnt;}x / 10;if (x 0) {return -1;}int targetDigit x % 10;int x2 n, cnt2 0;for (; x2 …

第14张 GROUP BY 分组

一、分组功能介绍 使用group by关键字通过某个字段进行分组&#xff0c;对分完组的数据分别 “SELECT 聚合函数”查询结果。 1.1 语法 SELECT column, group_function(column) FROM table [WHERE condition] [GROUP BY group_by_expression] [ORDER BY column]; 明确&#…

go函数传值是值传递?还是引用传递?slice案例加图解

先说下结论 Go语言中所有的传参都是值传递&#xff08;传值&#xff09;&#xff0c;都是一个副本&#xff0c;一个拷贝。 值语义类型&#xff1a;参数传递的时候&#xff0c;就是值拷贝&#xff0c;这样就在函数中就无法修改原内容数据。 基本类型&#xff1a;byte、int、bool…

UDP checksum(UDP校验和)

UDP校验和&#xff08;UDP checksum&#xff09;是一种用于检测传输中的UDP数据包在传输过程中是否发生错误的机制。UDP&#xff08;用户数据报协议&#xff09;是一种简单的无连接的传输层协议&#xff0c;它用于在网络中发送数据包&#xff0c;但不提供数据包的传输可靠性或顺…

使用pycharm调试程序——完全显示张量的数值

我在使用PyCharm调试程序时&#xff0c;发现有些张量因为shape过大&#xff08;数据量太多&#xff09;&#xff0c;导致该张量中的数值无法完全显示。下面就简单介绍怎样完全显示张量中的数值。 假设某个张量 inp_voxel 的 shape 为 torch.Size([5, 128, 128])&#xff0c;如…

MYSQL隔离性原理——MVCC

表的隐藏字段 表的列包含用户自定义的列和由系统自动创建的隐藏字段。我们介绍3个隐藏字段&#xff0c;不理解也没有关系&#xff0c;理解后面的undo log就懂了&#xff1a; DB_TRX_ID &#xff1a;6 byte&#xff0c;最近修改( 修改/插入 )事务ID&#xff0c;记录创建这条记…