Linux——进程通信
我们知道,进程具有独立性,各进程之间互不干扰,但我们为什么还要让其联系,建立通信呢?比如:数据传输,资源共享,通知某个事件,或控制某个进程。因此,让进程间建立通信是必不可少的。但如何通信呢?
根据进程的独立性,我们需要保证,让不同的进程看到同一份资源!但这个资源若是进程a建立的则b看不到,b建立的a看不到,因此,这份资源必须由操作系统提供!
进程间通信分类
一、.管道
管道在Linux中算是比较古老经典的一种通信方式
假设我们现在有一个进程(PCB,内存 mm_struct等结构),同时其有一个文件描述符表,对应了 某个正在加载的文件(文件在加载就有对应的struct _file、inode),现在我让进程fork出一个子进程,那么PCB等结构会以父进程为模板进行拷贝。但是内核缓冲区、inode也会拷贝吗?不会!文件只会被加载一次,(但struct_file会拷贝,子进程需要有自己的读写位置)那么这个文件是父子进程的共享资源。那么如果我们让父子进程中一方对文件进行写,一方进行读,不就形成了进程间通信了吗?这个以文件方式进行通信的方式我们称为管道。
实际上,两个进程的共享资源是文件内核缓冲区,而且,要让两个进程间通信,就没必要把数据刷新到磁盘。我们用一张图解释一下管道的原理
从图里我们也能看出,管道只能进行单向通信。
我们概念解释一下就是,从一个进程连接到另一个进程的一个数据流。
2.管道创建的接口
如果创建成功就返回0,失败返回-1,其中参数是一个输出型参数,输出管道所连的两个文件的fd。
3.按顺序创建一下管道
#include <iostream>
#include <string>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>// 让父进程写
// 让子进程读
int main()
{// 1. 创建管道int fds[2] = {0};int n = pipe(fds); // fds:输出型参数if (n != 0){//创建管道失败了std::cerr << "pipe error" << std::endl;return 1;}// Father -> read// Child -> write// 2. 创建子进程pid_t id = fork();if (id < 0){std::cerr << "fork error" << std::endl;return 2;}else if (id == 0){// 子进程// 3. 关闭不需要的fd,关闭readclose(fds[0]);int cnt = 0;while (true){std::string message = "hello";message += std::to_string(getpid());message += ", ";message += std::to_string(cnt);// fds[1]write(fds[1],message.c_str,message.size());cnt++;sleep(1);// break;}exit(0);}else{// 父进程// 3. 关闭不需要的fd,关闭writeclose(fds[1]);char buffer[1024];while (true){sleep(1);ssize_t n = read(fds[0], buffer, 1024);if (n > 0){buffer[n] = 0;std::cout << "child->father, message: " << buffer << std::endl;}else if(n == 0) {}close(fds[0]);break;std::cout << std::endl;}}return 0;
}
我们想让子进程写就需要把读的接口关闭,同理就需要关闭父进程的写入接口。而通常我们的fds[0]表示读,fds[1]表示写。我们这里实现让子进程向文件写入,然后让父进程读取。
3.管道的一些情况
在管道正常的情况下,如果管道为空,那么read会阻塞,如果管道写满了,write会阻塞,其中并不会出现在写入的过程中去读,也不会在读的过程中进行写,这种保护机制在管道本身就已经形成。如果管道写端关闭(比如子进程写入后退出),读端继续,知道读到0表示读到文件结尾。如果管道写端正常,读端关闭,操作系统会直接杀掉写入的进程(此时的写入已经没有意义)
4.管道的特性
我们以上说的管道的相关问题都指的是匿名管道。因为创建管道时并没有名称。关于匿名管道我们有以下特性:
可以用来进行具有血缘关系的进程间通信文件的生命周期随进程终止而终止,管道也是
只能做到单向数据通信
管道自带同步互斥等保护机制(读写有相对顺序)
二、管道通信的具体场景——进程池
我们刚才说到,如果管道为空,那么read方就会阻塞,知道有人写入才会读,假设有一个父进程fork出好几个子进程,此时其又为每一个子进程建立了管道,但此时在管道中没有内容,那么作为子进程就只能阻塞,等到父进程进行写入后进行通信。此时如果父进程向管道中写入某些命令,并让子进程们去执行,那么我们就可以像分派任务一样完成操作。像这样的模型我们称为进程池。
三、命名管道
上面我们的所有管道都是匿名管道,匿名管道没有名字,那么在通信时父子进程时如何看到这个管道的呢?->因为子进程继承了父进程的资源。但如果我想让任意两个进程间进行通信呢?此时就需要对管道进行命名了。
创建命名管道:
mkfifo name
我们来用一下,此时我们写入命令:echo "hello">fifo。我们发现卡住了,我们再启动一个终端并写入"cat <fifo"我们发现两个终端恢复正常并打印hello。相当于把内容写在管道然后等待另一端进行读,这就是基本的通信流程。
1.为什么叫命名管道
我们查看管道的详细信息发现,它是一个文件,有自己的inode,文件类型以p开头,也就是说它也有唯一的路径和文件名。这样我们可以用同一个文件系统路径,让两个进程看到同一份进程进行通信。其原理就是让操作系统只使用内核文件缓冲区,只是不刷新就可以了。
我们还有用函数来创建命名管道的方式:
第一个参数就是创建管道的路径,第二个参数是权限。创建成功返回0,出错返回-1
四、system V共享内存
我们知道,一个进程有自己的虚拟地址空间,然后通过页表映射到真实的物理地址,在虚拟地址空间中,有一块共享区,前面我们提到过,一般会把动态库映射到此部分,但现在如果我们在物理内存上开辟一块空间,然后让其通过页表映射到共享区,同样地,另一个进程也进行此操作,那么最终就会形成一个物理地址对应两个虚拟地址,就成功让两个进程看到同一份资源了。这就是共享内存。
共享内存可以在任何时刻在OS内存在多个。
创建共享内存的接口:shmget
第三个参数是一个标记位,我们常用的有IPC_CREAT和IPC_EXCL(宏),前者的作用是,如果内存不存在则创建,如果存在,将其获取并返回。对于后者,如果单独使用无意义,一般二者组合使用(|)。表示,如果内存不存在则创建,如果存在,出错返回。
返回值是一个shmid(共享内存标识符),可以看成数组下标,但和文件描述符相比,这个下标可以从0开始。失败返回-1.
第一个参数必须由用户手动输入,这个参数是用来保证两个进程所映射的是同一份内存,因为我们往往会有很多对共享内存同时存在,为了保证不出错,我们需要让每一份内存都具有唯一性,我们就可以用这个参数进行编号(具体输入由用户决定,能体现唯一性即可),这样我们就可以通过路径+id即可保证映射同一份资源。同时,系统中也有用来生成key值对应的函数:key_t ftok(路径,projid)
共享内存生命周期随内核!
已经开辟的共享内存要么手动释放,要么让OS重启。
五、共享内存的管理指令
1.查看已经开辟的共享内存——ipcs -m
2.删除共享内存——ipcrm -m shmid
3.控制共享内存的相关属性——shmctl函数
第二个参数我们传对应的宏选项即可,第三个参数用于获取共享内存的相关属性,一般置为nullptr。
比如我们可以用函数删除共享内存
shmctl( shmid,IPC_RMID,nullptr);
六、共享内存的特点
1.通信速度最快,相比于管道,共享内存只需要一次拷贝,提高了效率。
2.可以让两个进程在各自的用户空间共享内存块,但是没有加任何保护机制!
3.这个保护机制需要由用户自己完成,其中,共享资源被保护起来的话就称临界资源,而我们的代码并不完全都是访问共享内存的,只有访问公共资源的代码我们称临界区,对应的就是非临界区
相关文章:
Linux——进程通信
我们知道,进程具有独立性,各进程之间互不干扰,但我们为什么还要让其联系,建立通信呢?比如:数据传输,资源共享,通知某个事件,或控制某个进程。因此,让进程间建…...
AF3 create_alignment_db_sharded脚本create_shard函数解读
AlphaFold3 create_alignment_db_sharded 脚本在源代码的scripts/alignment_db_scripts文件夹下。 该脚本中的 create_shard 函数的功能是将一部分链(shard_files)中的所有对齐文件写入一个 .db 文件,并返回这些链的索引信息(字节…...
Jetpack Compose 实现主页面与局部页面独立刷新的最佳实践
在 Jetpack Compose 开发中,我们经常遇到这样的需求:主页面包含局部页面,主页面刷新时需要更新局部页面,同时局部页面也需要能独立刷新。本文将介绍几种优雅的实现方案。 核心需求 主页面刷新时能触发局部页面更新局部页面能独立…...
KingbaseES之数据库审计
项目提出要配置数据库审计,来满足分保测评得要求.正好最近做过审计测试,还原下审计配置. 一.开启审计 [kingbaserack1 ~]$ vi /data/data_mysql/kingbase.conf [kingbaserack1 ~]$ sys_ctl -D /data/data_mysql restart grep -r shared_preload_libraries /data/data_mysql/k…...
类的加载过程
1、加载 双亲委派模型(启动类》扩展类》应用类) 2、验证 文件格式验证(Class 文件格式检查)元数据验证(字节码语义检查)字节码验证(程序语义检查)符号引用验证(类的正确…...
小白工具视频转 3GP,多格式转换与数据安全的完美结合,在线使用
在众多在线视频转换工具中,小白工具的视频转 3GP 功能(https://www.xiaobaitool.net/videos/convert-to-3gp/ )凭借其出色的性能和丰富的功能脱颖而出,是进行视频格式转换的优质选择。 一、强大的多格式支持 这款工具支持 MP4、…...
六根觉性:穿透表象的清净觉知之光
在喧嚣的禅堂里,老禅师轻叩茶盏,清脆的声响划破沉寂。这声"叮"不仅震动耳膜,更叩击着修行者的心性——这正是佛教揭示的六根觉性在世间万相中的妙用。当我们凝视《楞严经》中二十五圆通法门,六根觉性犹如六道澄明之光&a…...
Redis的IO多路复用
1 传统的socket编码模型 传统 Socket 模型通常采用 多线程/多进程 或 阻塞 I/O 的方式处理网络请求。以下是典型实现步骤: 创建套接字(Socket) 步骤:调用 socket() 创建一个 TCP/UDP 套接字。通常把这个套接字称为【主动套接字】…...
数据结构和算法(六)--栈队列堆
一、栈 栈(stack)是限制插入和删除只能在一个位置上进行的表,该位置是表的末端,叫做栈顶(top)。它是后进先出(LIFO)的。对栈的基本操作只有 push(进栈)和 pop(出栈&#…...
js中显示为[object Object]
现象描述: 读取文件并解析数据,遇到变量在使用时异常,通过log输出进行调试,显示为[object,Object]。 分析: [object,Object]表示这是一个对象,其构造函数返回一个对象。 解决方法: 用JSON进行…...
安装matlab R2021b
安装步骤 说明: 以下步骤都是根据R2021b_Windows\Crack_ReadmeWin.txt文件里的内容翻译的。 1)打开安装包根目录,如下: 2)双击R2021b_Windows.iso文件,自动装载进虚拟光驱里,目录入下&…...
Redisson分布式锁深度解析:原理、源码与最佳实践
什么是Redisson分布式锁? 分布式锁是分布式系统中确保资源互斥访问的核心机制,而Redisson作为基于Redis的Java客户端,提供了高效且功能丰富的分布式锁实现。本文将深入剖析Redisson分布式锁的实现原理、核心机制及源码细节,并结合…...
isNaN、Number.isNaN、lodash.isNaN 的区别
isNaN、Number.isNaN、lodash.isNaN 的区别 一、isNaN() 的作用二、什么是 NaN?三、isNaN() 的必要性四、isNaN() 比较1. 全局的isNaN()2. Number.isNaN()3. lodash.isNaN() 五、总结六、附加 一、isNaN() 的作用 检查是否为 NaN 的值,是返回 true&…...
全面解析Flutter中的Stream用法及实际应用
Flutter中的Stream详解 目录 什么是StreamStream的分类Stream的基础用法Stream的常用方法实际应用场景完整示例:计数器应用总结参考文章 1. 什么是Stream 在Flutter开发中,Stream是一种强大的异步数据流处理工具。它类似于广播频道,能够持续推送数据…...
网络请求——微信小程序学习笔记
1. 前言 发起网络请求,即发起HTTPS网络请求 ,注意必须是HTTPS。 2. 使用前注意事项 使用前注意事项可参考官网文档: 基础能力 / 网络 / 使用说明 简单的来说,为了安全,服务器域名必须要备案,如果只是想…...
Oracle19C低版本一天遭遇两BUG(ORA-04031/ORA-600)
昨天帮朋友看一个系统异常卡顿的案例,在这里分享给大家 环境:Exadata X8M 数据库版本19.11 1.系统报错信息 表象为系统卡顿,页面无法刷出,登陆到主机上看到节点1 系统等待存在大量的 cursor: pin S wait on X等待 查看两个节…...
车机系统夏令时设置功能的说明
车机系统夏令时设置功能的说明 基本原理,夏令时,也就daylight saving time。据说古时候,电费比较贵,为了多采用白天自然光照明,通过行政的方式,调节上班时间。使大家能充分使用白天的时间干活,…...
DeepSeek+大数据分析快速应用落地
一、环境准备 1、准备一个 hive 的环境,并可以进行远程连接 2、环境中安装有 sqoop 和 mysql 3、DeepSeek 我使用的是 《问小白》 注册地址:打开问小白,填入我的分享码【1VYXOI】使用满血DeepSeek R1,零延迟、不卡、不限次、不…...
web前端开发:CSS的常用选择器
CSS常用选择器 CSS选择器是用于精准定位HTML元素并对其应用样式的核心工具。它的作用类似于“筛选器”,通过特定规则匹配文档中的元素,从而实现样式控制。 核心作用 定位元素 通过元素名称、类名、ID、属性等条件,快速找到需要样式化的目标元…...
Mathematica 中,将含有小数的表达式转换为整数或分数形式
具体方法和示例: 1. 使用 Rationalize 函数 Rationalize[x] 将小数 x 转换为最接近的有理数(分数形式),可指定精度容忍度。 示例: Rationalize[0.25] (* 输出: 1/4 *) Rationalize[3.14159, 0.001] (* 输出:…...
在 Ubuntu 下通过 Docker 部署 Mastodon 服务器的详细教程
大家好!今天我们来聊聊如何在 Ubuntu 系统上通过 Docker 部署 Mastodon 服务器。Mastodon 是一个开源的社交网络平台,类似于 Twitter,但更注重隐私和去中心化。Docker 则是一个非常流行的容器化平台,能够让我们轻松地打包、分发和…...
JavaScript基础-01(笔记)
前期:js变量 数据类型 数据类型检测 类型转换 数据类型 //// 基本数据类型 存放到栈// a.Number 数字类型(包含整数 小数)var num1var num1.23443var num2222// NaN 非数字类型或者不能转为数字(例:1,"1","1233…...
【C语言基础】C++ 中的 `vector` 及其 C 语言实现详解
一、C 中的 vector:动态数组的核心特性 1. 基本概念 vector 是 C 标准模板库(STL)中的动态数组容器,支持自动扩容、高效元素访问和丰富的操作接口。其核心特性包括: 动态内存管理:自动调整容量࿰…...
记录待办事项的便签软件有没有推荐的?
在快节奏的现代生活中,我们每天都要处理大量的工作任务和生活琐事,稍有不慎就可能遗漏重要事项。你是否经常遇到这样的情况:明明记得有件事要做,却怎么也想不起来是什么;或者手头同时有好几项任务,却不知道…...
华为OD机试真题——硬件产品销售方案(2025A卷:100分)Java/python/JavaScript/C++/C语言/GO六种最佳实现
2025 A卷 100分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析; 并提供Java、python、JavaScript、C、C语言、GO六种语言的最佳实现方式! 华为OD机试真题《硬件产品销售方案》: 目录 题目名称࿱…...
鸿蒙应用元服务开发-Account Kit未成年人模式订阅和处理用户信息变更
一、概述 通过订阅用户信息变更,您可以接收有关用户及其账户的重要更新。当用户取消元服务的授权信息、注销华为账号时,华为账号服务器会发送通知到元服务,元服务可以根据通知消息进行自身业务处理。 二、用户信息变更事件介绍 三、订阅用…...
优化 Dockerfile 性能之实践(Practice of Optimizing Dockerfile Performance)
优化 Dockerfile 性能之实践 构建 Docker 镜像时,Dockerfile 的性能会显著影响构建过程的效率。经过优化的 Dockerfile 可以缩短构建时间、最小化镜像大小并提高整体容器性能。在本文中,我们将探讨优化 Dockerfile 性能的最佳实践。 尽量减少层数 影响…...
OpenShift介绍,跟 Kubernetes ,Docker关系
1. OpenShift 简介 OpenShift是一个开源项目,基于主流的容器技术Docker及容器编排引擎Kubernetes构建。可以基于OpenShift构建属于自己的容器云平台。OpenShift的开源社区版本叫OpenShift Origin,现在叫OKD。 OpenShift 项目主页:https://www.okd.io/。OpenShift GitHub仓库…...
Go:包和 go 工具
引言 通过对关联特性分类,组成便于理解和修改的单元,使包与程序其他包保持独立,助力大型程序的设计与维护 。模块化让包可在不同项目共享、复用、发布及全球范围使用。 每个包定义不同命名空间作为标识符,关联具体包,…...
GIS开发笔记(5)结合osg及osgEarth实现虚线环形区域绘制
一、实现效果:输入中点坐标点、内圆半径、外圆半径,绘制坐标点所在高度的水平面的两个圆形形成环形区域。 二、实现原理: 创建中心点所在平面的圆形几何体,将其分别挂接到同一个节点上,再将该节点挂接到用户绘制组节…...
天线静电防护:NRESDTLC5V0D8B
一. 物联网天线的使用环境 1.1 联网天线广泛应用于智能家居领域,比如智能门锁、智能摄像头等设备中,通过天线实现设备与家庭网络的连接,用户可以远程控制和监控家居设备。以智能摄像头为例,它通过天线将拍摄的画面实时传输到用户…...
Linux进程相关选择题及解析
1. 关于Linux进程创建,以下说法正确的是? A. fork()函数调用后,子进程从父进程的fork()之后开始执行 B. fork()函数返回两次,父进程返回子进程PID,子进程返回0[10][11] C. exec函数族会替换当前进程的代码段,但保留数据段和堆栈 D. wait()函数只能等待直接子进程退出 答…...
Day(22)--网络编程习题
习题 以下是这些 TCP 通信练习题的 Java 代码实现及解析: TCP 通信练习 1 - 多发多收 客户端(Client1.java) java import java.io.IOException; import java.io.OutputStream; import java.net.Socket; public class Client1 {public…...
Kubernetes 节点摘除指南
目录 一、安全摘除节点的标准流程 1. 确认节点名称及状态 2. 标记节点为不可调度 3. 排空(Drain)节点 4. 删除节点 二、验证节点是否成功摘除 1. 检查节点列表 2. 检查节点详细信息 3. 验证 Pod 状态 三、彻底清理节点(可选…...
SM4密码算法的CPA攻击技术
SM4算法简介 可参见博文 SM4分组密码算法研究。 SM4密码算法的CPA攻击技术 相关功耗攻击(CPA)是侧信道功耗分析攻击中较为常见的攻击方法之一,攻击者利用密码算法执行过程中,在侧信道泄露的信息(如时序、能量、缓存等)和通信信道的消息(如明文、私钥等)进行测试,通过…...
Golang|KVBitcask
文章目录 初识KVbitcask论文详解 初识KV bitcask论文详解 论文地址:https://riak.com/assets/bitcask-intro.pdf理想的存储引擎,应该满足下面一些特点:...
【Python进阶】元组:不可变序列的十大核心应用
目录 前言:技术背景与价值当前技术痛点解决方案概述目标读者说明 一、技术原理剖析核心概念图解核心作用讲解关键技术模块技术选型对比 二、实战演示环境配置要求核心代码实现(10个案例)案例1:基础创建与访问案例2:解包…...
centos安装libheif
参考 解决docker: Error response from daemon: Get “https://registry-1.docker.io/v2/“:连接超时问题_error response from daemon :get-CSDN博客 HEIF编解码器安装 - navyum - 博客园 https://github.com/strukturag/libheif #升级gcc yum install centos…...
初步认识Model Context Protocol (MCP) Java SDK
1. Maven如何下载MCP Java SDK 基础配置(核心模块) 在您的pom.xml文件中添加以下依赖: <dependencyManagement> <dependencies> <dependency> <groupId>io.modelcontextprotocol.sdk</groupId> <artifactI…...
第三章 爬虫提速、selenium模块、requests模块进阶(终)
目录 一.requests进阶 (一)处理cookie (二)防盗链 (三)代理 二.爬虫提速 (一)线程池和进程池 (二)协程 (三)异步http请求-aio…...
unity使用内建组件给刚体增加重力
2019年3月9日11:10:24 unity开发中,有时候发现刚体上的重力不能满足我们的需要,可以通过使用内建组件Constant Force来增加重力: 在游戏对象上。请按照以下操作: 为Player添加一个名为Constant Force组件,选择Player在…...
Java开发中的设计模式之观察者模式详细讲解
观察者模式(Observer Pattern)是一种行为型设计模式,它定义了对象之间的一种一对多的依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都会自动收到通知并更新。这种模式在Java开发中非常常见,尤其是在事件驱…...
【学习笔记】计算机网络(九)—— 无线网络和移动网络
第9章 无线网络和移动网络 文章目录 第9章 无线网络和移动网络9.1 无线局域网WLAN9.1.1 无线局域网的组成9.1.2 802.11局域网的物理层9.1.3 802.11局域网的MAC层协议CSMA 协议CSMA/CD 协议 - 总线型 - 半双工CSMA/CA 协议 9.1.4 802.11局域网的MAC帧 9.2 无线个人区域网WPAN9.3…...
一个基于Django的写字楼管理系统实现方案
一个基于Django的写字楼管理系统实现方案 用户现在需要我用Django来编写一个写字楼管理系统的Web版本,要求包括增删改查写字楼的HTML页面,视频管理功能,本地化部署,以及人员权限管理,包含完整的代码结构和功能实现&am…...
C++面试考点:类(class)
1、类的定义 C中的类提供了面向对象编程、继承与多态的机制。其构成包括成员(各种自定义数据)、行为(定义的函数操作)、封装(private、public、protected)。核心是了解类的继承机制,以及各种封装…...
ThreadPoolExecutor 多线程用requests请求一个地址的时候为什么会报错,而多进程用requests请求一个地址的时候不会报错,为什么?
网络请求行为 多线程:requests 库底层依赖 urllib3,而 urllib3 使用连接池管理网络请求。在多线程环境中,连接池可能会因为线程间的竞争导致连接泄漏或超时。 多进程:每个进程独立管理自己的连接池,因此不会出现线程间…...
数据库脱裤
假设你已经getshell 找到mysql账号密码。 网站要连接mysql,就需要把mysql的账号密码保存在一个php文件中,类似config.php、common.inc.php等,在shell中,读取这些文件,找到其中信息即可 下面是一些常见平台的配置文…...
十二,<FastApi>中间件
什么是中间件? "中间件"是一个函数,它在每个请求被特定的路径操作处理之前,以及在每个响应之后工作. 代码示例: from fastapi import FastAPI, Response from fastapi import Request import uvicornapp FastAPI()app.middleware("http") async def m2…...
欢迎使用Markdown编辑器
使用Markdown编辑器 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个注…...
RabbitMQ架构原理及消息分发机制
RabbitMQ架构原理及消息分发机制 在现代分布式系统中,消息队列是不可或缺的组件之一。它不仅能够解耦系统模块,还能实现异步通信和削峰填谷。在众多消息队列中,RabbitMQ 因其高并发、高可靠性和丰富的功能而备受青睐。本文将从 RabbitMQ 的基…...