Linux:SystemV通信

目录

一、System V通信

二、共享内存

代码板块

总结

三、信号量

信号量理论

信号量接口


一、System V通信

        System V IPC(inter-process communication),是一种进程间通信方式。其实现的方法有共享内存、消息队列、信号量这三种机制。

        

二、共享内存

        进程间通信的本质就是让不同进程看到同一份资源,比如匿名管道是利用了父子进程之间继承机制,命名管道是利用路径找到同一个文件。

        共享内存本质也是让不同进程看到同一份资源。

        学习进程的通信方法,本质都是在学习是如何让不同进程使用到同一份资源的

  • 共享内存机制

        第一步,由操作系统在内存中开辟内存空间。

        第二步:操作系统把共享内存的地址通过页表映射到进程地址空间中。

        另一个进程同样如此。

        进程通过这块内存通信,通信完毕后,还有移除映射、释放共享内存等步骤。

  • 共享内存的细节 

        实际上,会有多个进程都采用共享内存的方式通信,因此会有多个被开辟的小内存空间,用来通信,操作系统同样要对这些个共享内存作管理,同样要标识唯一的共享内存,这个关键字在Linux下的类型命名为key_t

        于是,我们要理解共享内存的本质,就是要理解,两个进程究竟是通过怎样的方式拿到同一个key_t的。

        先来认识一下,Linux下创建共享内存的系统调用接口。

man 2 shmget


        第一个参数,key_t key ,这个参数就是用来标识唯一的共享内存空间的,由用户传入,并不是由操作系统指定。

        原因:当一个进程想要和另一个进程通信,A进程是无法得知B进程的一切信息的,它只能自己申请创建一块共享内存空间,然后想办法让B进程也能访问到这个特定的内存空间,但是在操作系统看来,它管理这多个这样的内存空间,操作系统是不知道A和B是想要通信的,也就无法将这个唯一标识传给B进程。

        因此这个参数key只能由用户设置

        但是,直接设置这样一个标识符可能会大概率和其他共享内存空间的标识符冲突,因此有专门的一个函数,可以根据用户设置的字符串来生成唯一且随机的一个标识符。


 

man 3 ftok

        想要通信的两个进程,到时候在源代码中约定一样的字符串,根据这个函数生成共享内存空间的唯一标识符,由其中一个进程向操作系统申请创建这块内存空间,至此,两个进程都能拿到同一块共享内存空间了,这便是System V共享内存的实质。


        第二个参数,指定共享内存空间的大小

        第三个参数,用来指定特殊标志,传参选项有IPC_CREATIPC_EXCL

        传参形式有三种:

        只传IPC_CREAT:如果要创建的共享内存空间不存在,就创建它,如果已经存在,则直接使用它。

        只传IPC_EXCL:无意义。

        传参IPC_CREAT | IPC_EXCL: 如果要创建的共享内存空间不存在,就创建它,如果已经存在,则报错!!


代码板块

  • 1.先实现获取key

//可以随机定义
const char* pathname = "/home/utocoo/Desktop/linux/241221";
const int pri_id = 0x67;
//获取key
key_t CreatKeyOrDie()
{

    key_t key = ftok(pathname,pri_id);
    if(key < 0)
    {
        cerr << "ftok error,errno->" << errno<<"->" << strerror(errno) << endl;
        exit(1);
    }
    return key;
}

  • 2.再根据key申请共享内存 

//根据Key申请共享内存
int CreatShmOrDie(key_t key,size_t size,int flag)
{
    int shmid = shmget(key,size,flag);
    if(shmid < 0)
    {
        cerr << "shmget error,errno->" << errno << "->" << strerror(errno) << endl;
        exit(2);
    }

    return shmid;
}

        然而,在通信的用户看来,创建共享内存时,只需要指定key和内存大小即可,所有可以把这个函数再次封装。

        并且对于要创建内存的进程而言,比如A进程,创建内存时,如果不存在就创建,如果存在则报错;而对B进程而言,如果内存已经存在,只需要获取它的shmid即可。

        

//A进程创建
int CreatShm(key_t key,size_t size)
{
    CreatShmOrDie(key,size,IPC_CREAT | IPC_EXCL | 0666);
}
//B进程不用再创建,只需要获取即可
int GetShm(key_t key,size_t size)
{
    CreatShmOrDie(key,size,IPC_CREAT);
}

        再来认识一下创建共享内存空间函数shmget的返回值int shmid,这个返回值同样可以标识唯一的一块内存空间,它和另一个标识符key又有什么样的关联?

        key这个关键字,是在内核级别,帮助操作系统标识唯一的共享内存空间。

        而shmget的返回值,是帮助用户来管理这块内存空间,作为用户来讲,往往是通过shmid来使用各种各样的接口。

  • 释放共享内存空间

        进程退出后,如果用户不主动释放申请的共享内存,那么这块内存的生命周期是一直跟随着操作系统的,只有重启才会重新初始化这块内存。

        释放共享内存的接口为shmctl+特定参数

man 2 shmctl

        第三个参数的类型就是操作系统用来描述共享内存的结构体,cmd的取值范围在man手册中也有说明。

//释放共享内存
void DeleteShm(int shmid)
{
    int r = shmctl(shmid,IPC_RMID,nullptr);
    if(r < 0)
    {
        cerr << "delete shm error,errno->" << errno << "->" << strerror(errno) << endl;
        exit(3);
    }
    else 
    {
        cout << "delete shm->" << shmid << "success" << endl;
    }
}

        关于释放共享内存,上面介绍的是在代码中我们利用系统调用接口实现,也可以在命令行中通过指令完成释放。

        ipcs指令查看SystemV通信的所有介质。

ipcs

 

        ipcs -m则只查看所有的共享内存。

ipcs -m

        ipcrm -m 指定的shmid则在命令行中删除指定shmid的共享内存。

ipcrm -m shmid

  •  将内存空间挂载或者说映射到进程的虚拟地址空间中

        所用到的接口是shmat

        第二个参数,shmaddr用来指定要将指定shmid的共享内存映射到虚拟地址空间的哪个地方,第三个参数shmflag默认传0即可,特殊用途可以传特殊参数,这些在man手册中均有说明。

        需要说明的是返回值 

        shmat会返回虚拟地址空间段地址,否则返回(void*)-1

//映射到进程上面
void* ShmAttah(int shmid)
{
    char* addr = (char*)shmat(shmid,nullptr,0);
    if((int64_t)addr == -1)
    {
        cerr << "ShmAttach error,errno->" << errno << "->" << strerror(errno) << endl;
        return nullptr;
    }
    return addr;
}

  • 既然有挂载,也就应该有取消挂载 

        相应的接口为shmdtdt是detach的缩写

总结

         共享内存的特征:由于共享内存,当写进程不再向内存中写数据的时候,读进程还是会一直从内存中读数据,共享内存并不提供进程间通信的同步机制,这一点不同于管道通信,这是它的缺点。

        然而,正因为共享内存的缘故,当写进程向内存中写完数据后,读进程可以立马从内存中读取到数据,这个过程又不同于管道通信,因为管道通信是不断的拷贝,因此,共享内存的通信方式却是最快的通信方式,这是它的优点。

        因为共享内存块注定这种通信方法无法提供通信同步机制,因此,可以在共享内存通信的基础上,提供一个管道,利用管道来同步、利用共享内存来通信。

三、信号量

信号量理论

  • 同步和互斥。

        互斥机制:像共享内存这样的通信方式中,写进程在写的过程中,如果读进程可以随时随地的读,最终可能造成数据不一致的情况,因此,为了避免这种数据不一致的情况,引入互斥机制让一份资源只能由一个进程在享用,另一个进程想要享用,必须要排队等待。

        同步机制:引入互斥机制后,个别进程可能长时间享用一份资源,导致其他进程在一段时间内都无法享用该资源,因此,引入同步机制,来解决个别进程长时间占用资源的问题

  • 临界资源

        被保护的资源,进程之间互斥访问的资源,称为临界资源。

        用来访问临界资源的代码,被称为临界区,同时,其他代码被称为非临界区,而保护公共资源是互斥访问本质就是在保护临界区,显然,如何保护临界区,是由程序员来实现。

  • 什么是操作的原子性

        对临界资源的操作,只有两种状态,要么还没开始访问,要么已经结束访问。

  • 临界资源的访问

        将临界资源,也就是一块内存,视为一个整体,这个时候一个进程访问,其他进程必须等待,考虑到效率问题,将这块内存划分为多个小内存,比如100MB的共享内存划分为多个4KB的小内存,让多进程互斥的访问小内存,可以提高效率。

        这种设计需要满足:

        1.被划分的小内存数量是有限的,因此,必须限制多进程数量,只允许一定数量的进程访问。

        2.如何合理分配小内存给多个进程。

  • 什么是信号量

        “信号量”往往是在说信号量机制,我们已经知道信号量机制是SystemV通信方式的一种,是用来帮助进程通信的,那么要如何理解。

        信号量本质是一个计数器,用来表述临界资源的数量,计数器有加减操作来表示临界资源数量的变化,某一个进程对这个计数器可能做加或者减操作,造成计数器值的改变要求其他进程也能看到,符合“让不同的进程看到同一份资源”这一原理,因此,信号量资源本质也是共享资源。

  • 信号量不能用整型变量表示

        一是因为整型变量不能被共享,二是因为整型变量的加减操作不满足原子性。

  • 信号量机制

        进程在访问临界资源的时候,

        通常是先要申请资源,信号量做减法,也称P操作。

        申请成功则表示对资源的预订,不一定立刻访问,申请失败表示资源数不够,进程必须等待

        资源访问完毕后进程释放资源,信号量做加法,也称V操作。

        PV操作就是进程在保护临界资源的过程。

  • 信号量本身就是临界资源

        信号量本身就是临界资源,必须要有申请、释放信号量的过程。

信号量接口

  • 申请信号量

        semget。

  • 释放信号量

        semctl。

  • PV操作

        semop

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

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

相关文章

2025.1.15——七、cookie注入

题目来源&#xff1a;ctfhub技能树 目录 一、打开靶机&#xff0c;整理已知信息 二、解题步骤 step 1&#xff1a;按F12查看cookie信息&#xff0c;见上 step 2&#xff1a;bp抓包修改cookie信息&#xff0c;确认注入类型 step 3&#xff1a;查看字段数 step 4&#xff…

【简博士统计学习方法】第2章:3. 感知机——学习算法之原始形式:算法解说

3. 感知机——学习算法之原始形式&#xff1a;算法解说 3.1 学习问题 给定训练数据集&#xff1a; T { ( x 1 , y 1 ) , ( x 2 , y 2 ) ⋯ , ( x N , y N ) } T\left\{\left(x_{1}, y_{1}\right),\left(x_{2}, y_{2}\right) \cdots,\left(x_{N}, y_{N}\right)\right\} T{(x…

【Flink系列】10. Flink SQL

10. Flink SQL Table API和SQL是最上层的API&#xff0c;在Flink中这两种API被集成在一起&#xff0c;SQL执行的对象也是Flink中的表&#xff08;Table&#xff09;&#xff0c;所以我们一般会认为它们是一体的。Flink是批流统一的处理框架&#xff0c;无论是批处理&#xff08…

web漏洞扫描有什么作用?web漏洞扫描原理

Web漏洞扫描在网络安全领域中扮演着至关重要的角色&#xff0c;web漏洞扫描有什么作用&#xff1f;Web漏洞扫描能够自动化地检测Web应用中的潜在安全漏洞&#xff0c;包括但不限于SQL注入、跨站脚本&#xff08;XSS&#xff09;、跨站请求伪造&#xff08;CSRF&#xff09;、文…

【Idea启动项目报错NegativeArraySizeException】

项目场景&#xff1a; Idea启动项目报错&#xff08;打包不报错&#xff09;&#xff0c;项目在服务器部署运行没有问题&#xff0c;尝试了重启idea、重启电脑、maven clean/install 都不行 maven-resources-production:sample: java.lang.NegativeArraySizeException: -5833…

小程序组件 —— 31 事件系统 - 事件绑定和事件对象

小程序中绑定事件和网页开发中绑定事件几乎一致&#xff0c;只不过在小程序不能通过 on 的方式绑定事件&#xff0c;也没有 click 等事件&#xff0c;小程序中绑定事件使用 bind 方法&#xff0c;click 事件也需要使用 tap 事件来进行代替&#xff0c;绑定事件的方式有两种&…

sparkSQL练习

1.前期准备 &#xff08;1&#xff09;建议先把这两篇文章都看一下吧&#xff0c;然后把这个项目也搞下来 &#xff08;2&#xff09;看看这个任务 &#xff08;3&#xff09;score.txt student_id,course_code,score 108,3-105,99 105,3-105,88 107,3-105,77 105,3-245,87 1…

GIFT ICA 下载记录

1.帮助文档 Group ICA/IVA Of fMRI Toolbox&#xff1b;【GIFT介绍】 Group ICA of fMRI Toolbox (GIFT) Walk Through&#xff1b;【流程介绍】 GIFT v1.3c Functions Srinivas Rachakonda, Eric Egolf and Vince Calhoun【流程解释】 2.下载记录 从官网下载程序包&#xff0…

从零深度学习:(2)最小二乘法

今天我们从比较简单的线性回归开始讲起&#xff0c;还是一样我们先导入包 import numpy as np import torch import matplotlib as mpl import matplotlib.pyplot as plt a torch.arange(1,5).reshape(2,2).float() a 我们利用刚刚导入的画图的包将这两个点画出来&#xff0…

02JavaWeb——JavaScript-Vue(项目实战)

一、JavaScript html完成了架子&#xff0c;css做了美化&#xff0c;但是网页是死的&#xff0c;我们需要给他注入灵魂&#xff0c;所以接下来我们需要学习 JavaScript&#xff0c;这门语言会让我们的页面能够和用户进行交互。 1.1 介绍 通过JS/js效果演示提供资料进行效果演…

【Flink系列】5. DataStream API

5. DataStream API DataStream API是Flink的核心层API。一个Flink程序&#xff0c;其实就是对DataStream的各种转换。具体来说&#xff0c;代码基本上都由以下几部分构成&#xff1a; 5.1 执行环境&#xff08;Execution Environment&#xff09; Flink程序可以在各种上下文…

大模型高并发部署方案探究

版本 内容 姓名 时间 V1.0 新建 xx 2025-01-16 声明&#xff1a;只是进行探究&#xff0c;后续真正实践后&#xff0c;会更新新的内容 前置条件&#xff1a;70B的模型&#xff0c;并发要求200 性能测试参考链接 Benchmarking LLM Inference Backends :表明一台A100(8…

MIAOYUN信创云原生项目亮相西部“中试”生态对接活动

近日&#xff0c;以“构建‘中试’生态&#xff0c;赋能科技成果转化”为主题的“科创天府智汇蓉城”西部“中试”生态对接活动在成都高新区菁蓉汇隆重开幕。活动分为成果展览、“中试”生态主场以及成果路演洽谈对接三大板块。在成果展览环节&#xff0c;成都元来云志科技有限…

pytest-instafail:让测试失败信息即时反馈

pytest-instafail&#xff1a;让测试失败信息即时反馈 前言一、简介二、优势三、安装与使用3.1 未安装时运行情况3.2 安装3.3 已安装时运行情况3.3 pytest.ini 配置选项 四、对比 总结 前言 当测试用例数量庞大时&#xff0c;定位测试失败的原因往往耗时费力。此时&#xff0c;…

低代码平台:技术复杂性的系统简化

在传统开发模式下&#xff0c;应用构建需要经历需求分析、代码开发、测试部署等多环节&#xff0c;流程繁琐且耗时&#xff0c;往往成为企业技术创新的瓶颈。低代码平台通过模块化和自动化技术重新定义开发流程&#xff0c;使开发者能够在较短时间内实现复杂的应用功能&#xf…

精度论文:【Focaler-IoU: More Focused Intersection over Union Loss】

Focaler-IoU: 更聚焦的交并比损失 Focaler-IoU: More Focused Intersection over Union Loss Focaler-IoU: 更聚焦的交并比损失I. 引言II. 相关工作III. 方法IV. 实验V. 结论 原文地址&#xff1a;官方论文地址 代码地址&#xff1a;官方代码地址 摘要——边界框回归在目标检…

“AI智慧化服务系统:未来生活的智能管家

在当今快速发展的科技时代&#xff0c;人工智能&#xff08;AI&#xff09;正以前所未有的速度改变着我们的生活。AI智慧化服务系统作为这一变革的前沿技术&#xff0c;正在逐渐成为我们未来生活的智能管家。它们不仅提高了服务效率&#xff0c;还为我们带来了更加个性化和便捷…

nginx 修改内置 404 页面、点击劫持攻击。

1、在部署前端项目的目录下增加 404.html 页面&#xff1a;/opt/web/404.html。 2、在 nginx 配置中增加 404 配置&#xff1a; root /opt/web; # 设置根目录的配置error_page 404 404.html; location /404.html {root /opt/web;# 指定 404 页面所在的根目录internal;# 确保…

网络密集型应用的Linux网络缓冲区参数优化

一、网络IO密集型 1.哪些应用属于网络IO密集型应用 文件上传、下载服务器&#xff0c;实时大数据同步复制&#xff0c;Kafka巨量数据QPS生产消费环境&#xff0c;CDN等环境都是网络IO密集型的服务应用 2.知识来源 在《kafka权威指南2》书中环境搭建的网络小节写到了几个参数…

npm发布组件(vue3+webpack)

1.初始化Vue项目 vue create my-app 2.本地运行 npm run serve 3.新增目录和文件 1. src/package/index.js 2. src/package/wlz-btn/index.vue 3. src/package/wlz-input/index.vue // src\package\index.js import WlzBtn from "./wlz-btn"; import WlzInput …