Linux下的进程通信之system V共享内存

news2024/9/22 13:29:41

目录

使用system V共享内存进行进程间通信:

获取共享内存shmget

将共享内存关联到进程

去关联共享内存

删除共享内存

简易模拟实现server和client之间的通信:

服务端代码:

客户端代码:

共享内存的特点: 

其他进程间通信的方式

IPC之间的联系


上篇提到进程间通信的方式管道,system V共享内存也是一种进程间通信的方式。

使用system V共享内存进行进程间通信:

获取共享内存shmget

使用获取共享内存函数第一个参数key是标识共享内存的一个唯一数字,相当于两个进程之间约定的同一个文件进行通信。它标识了两个进程,将使用的同一块共享内存进行通信,即可以通过ftok函数通过传入的参数获取唯一的数值,但是这个函数不保证生成的数值唯一。

ftok函数的第一个参数是路径,第二个参数是一个整数,但是函数内部实现只会使用低8bit位的数生成key,创建失败时返回-1。

第二个参数是size表示要创建共享内存的大小,一般设置为4K的整数倍,也就是4096byte的整数倍,这是因为物理内存是以页为单位的,每页就是4KB的大小,假设传入4097字节,OS会分配8KB,但是用户只能使用4097字节的大小。

第三个参数是创建共享内存的方式,是使用宏作为参数。

可用宏有:

IPC_CREAT表示不存在共享内存就创建之,存在就返回之。

IPC_EXCL,这个宏必须搭配上面的宏一起使用,表示如果存在就错误返回,如果不存在就创建共享内存,这两个宏搭配使用,可以保证创建的共享内存是新的。

函数的返回值是共享内存的id即shmid。

将共享内存关联到进程

        使用共享内存之前,需要用我们的关联共享内存函数去关联我们的共享内存,使用的时候像使用从堆申请的内存一样去使用即可,使用完之后,需要调用系统调用去关联,最后调用系统调用或使用命令行去删除共享内存。本质上是共享内存和进程产生关联,也就是页表建立了进程地址空间共享区和物理内存的映射。

使用shmat函数:

第一个参数shmid是共享内存id,是shmget函数的返回值。

第二个参数shmaddr是指定关联到进程地址空间的某一个地址,常用NULL、nullptr表示先关联到系统可以获得到的地址。

第三个参数shmflg是设置关联共享内存的属性,可传入0表示读写权限,传入SHM_RDONLY表示只读权限。

当关联失败时会返回(void*) -1,比如shmget函数第三个参数没有带入文件权限,默认文件权限就是0,关联共享内存时就会失败。

去关联共享内存

使用shmdt去掉之前的关联

创建的共享内存是在系统内核中维护的,所以它的生命周期是属于内核的,如果不通过命令行或者系统调用的方式显式删除掉共享内存,只就只能通过重启操作系统来删除共享内存的,所以共享内存的生命周期是随内核的。

删除共享内存

可以使用shmctl函数,第一个参数是shmid,传入第二个参数是IPC_RMID即可。

或者在命令行使用ipcs -m查看共享内存,使用ipcsrm -m 共享内存id删除共享内存:

 

简易模拟实现server和client之间的通信:

server服务端进行如下步骤:

    1.创建key,并获取shm,返回shmid

    2.关联共享内存

    3.获取共享内存内容,直接打印

    4.去关联共享内存

    5.删除共享内存

服务端代码:

#include "util.hpp"

int main()
{
    // 1.创建key,并获取shm,返回shmid
    key_t key = CreateKey();
    int shmid = shmget(key, MEM_SIZE, IPC_CREAT | IPC_EXCL | 0666);
    if (shmid < 0)
    {
        cerr << "shmget:" << strerror(errno) << endl;
        return 2;
    }

    // 2.关联共享内存
    char *shm = (char *)shmat(shmid, nullptr, 0);
    cout << "attach success" << endl;
    if (shm == (void *)-1)
    {
        cerr << "shmat error" << endl;
        return 3;
    }

    // 3.使用共享内存
    while (1)
    {
        printf("%s", shm);
        if (strncasecmp(shm, "QUIT", 4) == 0) // 用户控制退出,忽略大小写,需要使用strncasecmp
        {
            cout << "server quit!" << endl;
            break;
        }
        sleep(5);
    }

    // 4.去关联共享内存
    shmdt(shm);
    cout << "detach shm success!" << endl;

    // 5.删除共享内存
    shmctl(shmid, IPC_RMID, nullptr);
    cout << "remove shm success!" << endl;

    return 0;
}

客户端的步骤与服务端基本相同,先创建key值,然后获取共享内存,然后挂接共享内存,最后是使用共享内存,不需要进行删除共享内存,因为服务端会完成此工作。

客户端代码:

#include "util.hpp"

int main()
{
    // 1.创建key,并获取shm,返回shmid
    key_t key = CreateKey();
    int shmid = shmget(key, MEM_SIZE, IPC_CREAT | 0666);
    if (shmid < 0)
    {
        cerr << "shmget:" << strerror(errno) << endl;
        return 2;
    }

    // 2.关联共享内存
    char *shm = (char *)shmat(shmid, nullptr, 0);
    if (shm == (void *)-1)
    {
        cerr << "shmat error" << endl;
        return 3;
    }

    // 3.使用共享内存
    while (1)
    {
        printf("Please Enter#");
        fflush(stdout);
        ssize_t s = read(0, shm, MEM_SIZE); // 从键盘信息写入共享内存
        if (s > 0)
            shm[s - 1] = '\0';
        char *str = shm;
        if (strncasecmp(str, "QUIT", 4) == 0) // 用户控制退出,忽略大小写,需要使用strncasecmp
        {
            cout << "client quit!" << endl;
            break;
        }
    }

    // 4.去关联共享内存
    shmdt(shm);
    cout << "detach shm success!" << endl;

    return 0;
}

公共头文件代码:

#include <sys/ipc.h>
#include <sys/shm.h>
#include <iostream>
#include <unistd.h>
#include <errno.h>
#include<string.h>
using std::cerr;
using std::endl;
using std::cout;
#define IPC_PATH "/home/ys/os-learning-code/oscall/IPC"
#define PROJ_ID 0x66
#define MEM_SIZE 4096
key_t CreateKey()
{
    key_t key = ftok(IPC_PATH, PROJ_ID);
    if (key == -1)
    {
        cerr << "ftok create key error" << endl;
        exit(1);
    }
    return key;
}

测试结果:

共享内存的特点: 

共享内存的特点如下,首先它没有访问控制,所以它是所有进程间通信方式中,通信速度最快的,其次共享内存没有访问控制,共享内存是进程之间访问看到同一份的资源,即临界资源,临界资源没有受到访问控制,即没有互斥和同步机制,会导致访问临界资源出现问题。

其他进程间通信的方式

还有消息队列,信号量等等。

信号量的本质是一个计数器,是一种预定的机制,类似于买电影票,预定的座位一样,只要拿到了票,就相当于获得了座位,就相当于获得了访问临界资源的权利,所以申请信号量的操作就相当于申请临界资源,对计数器的操作必须是原子性的才能保证,信号量和消息队列的生命周期也都是随内核的。

IPC之间的联系

内核在底层实现各种进程间通信的内核结构中,每种内核结构的第一个字段都是ipc_perm。操作系统用指针指向的内核结构,当访问不同类型的IPC资源时进行强制类型转换,即可访问到不同类型的ipc资源,这样子去定义结构,有利于OS以统一的规则管理IPC资源。

 

ipc_perm结构体的字段中包含key等:

 使用ipcs -m/-q/-s/-a命令查看共享内存,消息队列,信号量,或所有IPC资源。

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

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

相关文章

solrCloud一:zookeeper集群搭建

SolrCloud是基于Solr和Zookeeper的分布式搜索方案&#xff0c;它的主要思想是使用Zookeeper作为集群的配置信息中心。SolrCloud是Solr的一种分布式部署方式 &#xff0c;当索引越来越大时&#xff0c;一个单一的系统无法满足空间和查询效率上的要求&#xff0c;这个时候往往需要…

SpringCloud(11):Hystrix请求合并

1 简介 如图&#xff0c;多个客户端发送请求调用(消费者)项目中的findOne方法&#xff0c;这时候在这个项目中的线程池中会发申请与请求数量相同的线程数&#xff0c;对EurekaServiceProvider(服务提供者)的getUserById方法发起调用&#xff0c;每个线程都要调用一次&#xff0…

圆满落幕!56 人参加,龙蜥社区技术委员会、运营委员会会议顺利完成

1 月 13 日&#xff0c;龙蜥社区分别召开了第 10 次技术委员会会议和第 14 次运营委员会会议&#xff0c;来自 21 家理事单位的委员代表出席。两个会上分别总结和回顾了龙蜥社区 2022 年度整体技术和运营发展情况&#xff0c;就社区产品、重要技术决策、社区治理、2023 年度运营…

塔望3W消费战略全案丨火出天际的预制菜,能否拯救开饭焦虑?

2022年6月塔望咨询开设塔望食品大健康消费研究院&#xff08;简称塔望食研院&#xff09;栏目&#xff0c;塔望食研院以“为食品行业品牌高质量发展赋能”为理念&#xff0c;将不定期发布食品大健康行业研究、消费研究报告。塔望食研院致力于结合外部数据、消费调研数据、企业内…

Web(九)

Web服务器软件Tomcat web服务器软件&#xff1a; 服务器&#xff1a;安装了服务器软件的计算机 服务器软件&#xff1a;接收用户的请求&#xff0c;处理请求&#xff0c;做出响应 web服务器软件&#xff1a;接收用户的请求&#xff0c;处理请求&#xff0c;做出响应。 在…

说话人识别损失函数的PyTorch实现与代码解读

概述 说话人识别中的损失函数分为基于多类别分类的损失函数&#xff0c;和端到端的损失函数&#xff08;也叫基于度量学习的损失函数&#xff09;&#xff0c;关于这些损失函数的理论部分&#xff0c;可参考说话人识别中的损失函数本文主要关注这些损失函数的实现&#xff0c;…

SQL 分组条件深入剖析

问题在 stackoverflow 网站上看到这样一个 SQL 分组条件的需求&#xff0c;需求看似挺简单&#xff0c;但能把 SQL 写正确对于新手来说也不容易&#xff0c;我们拿过来深入剖析一下&#xff0c;数据如下&#xff1a;需求是查找只有Ready 状态的设备。解答自然思路&#xff1a;按…

寅辞旧岁,卯定常虹丨ASKO洗碗机“净”护新春团圆时刻

农历新年是一年中最重要的节日&#xff0c;但过去三年的特殊时光阻碍了很多人的归乡之行&#xff0c;如今当阴霾逐渐散去&#xff0c;必然会引来大规模的新年归乡潮&#xff0c;奔赴一个久违的团圆年。美馔佳宴是新春佳节的永恒命题&#xff0c;新年家里少不了亲友的光临&#…

Windows 7的最后一个版本

前天推送的文章介绍了&#xff0c;在1月10日微软发布了最后一个补丁后&#xff0c;微软为Windows7提供的所有更新(包括收费的ESU)已经完全终止。以后再有新的补丁&#xff0c;则为第三方平台提供的非官方版的了。 早在2022年9月份&#xff0c;微软就发布了支持安全启动UEFI的补…

DocPrompt代码实现与模型微调

数据预处理阶段 PaddleOCR PP-Structure&#xff1a;这个库其实是用于版面分析的一个开源库&#xff0c;参见&#xff1a;github: Layout-Parser/layout-parserhttps://github.com/Layout-Parser/layout-parser 代码推理阶段 Paddle-Inferencehttps://paddle-inference.readt…

图形编辑器:工具管理和切换

大家好&#xff0c;我是前端西瓜哥。今天我们看看对于一款图形编辑器&#xff0c;应该怎么去实现工具&#xff0c;比如绘制矩形、选中工具&#xff0c;以及如何去管理它们的。 项目地址&#xff0c;欢迎 star&#xff1a; https://github.com/F-star/suika 线上体验&#xff1a…

【改进篇】Python实现VRP常见求解算法——蚁群算法(ACO)

基于python语言&#xff0c;实现经典蚁群算法&#xff08;ACO&#xff09;对车辆路径规划问题&#xff08;CVRP&#xff09;进行求解&#xff0c; 优化代码结构&#xff0c;改进Split函数 目录往期优质资源1. 适用场景2. 改进效果对比2.1实验结果2.2 改进前后算法性能对比3. 求…

臻图信息构建数字孪生港口船舶停靠管理系统,赋能港口创新发展

我国的港口不仅是船只停靠的避风港&#xff0c;也是现代渔业发展和管理的中心。随着国内港口业的不断发展&#xff0c;国务院在《现代综合运输体系发展“十四五”规划》中提出&#xff0c;要自动化、数字化、智能化等技术来完善监管体系建设。 ​ 随着科技兴港战略的提出&…

“零”代码改动,静态编译让太乙Stable Diffusion推理速度翻倍

作者&#xff5c;梁德澎 AI 作图领域的工具一直不尽人意&#xff0c;直到去年 8 月 Stable Diffusion 开源&#xff0c;成为AI 图像生成领域无可争辩的划时代模型。 为了提升其推理效率&#xff0c;OneFlow 首度将 Stable Diffusion 模型加速至“一秒出图”时代&#xff0c;极…

2023牛客寒假算法基础集训营2(11/12)

Tokitsukaze and abn (easy)Tokitsukaze and abn (medium)要使abn&#xff0c;那么转换一下就是bn-a&#xff0c;所以只需要计算[n-L,n-R]和[L,R]相交的部分即可AC代码&#xff1a;#include <bits/stdc.h> using namespace std; using LL long long; int main() {ios::s…

6. 基本数据类型

1. Python 中的变量不需要声明 每个变量在使用前都必须赋值&#xff0c;变量赋值以后该变量才会被创建。在 Python 中&#xff0c;变量就是变量&#xff0c;它没有类型&#xff0c;我们所说的"类型"是变量所指的内存中对象的类型。 counter 100 # 整型 mile…

关于Win11打开文档总是提示“选择一个程序打开”的问题

这边异常情况&#xff1a; 使用的360浏览器下载回来的文档、微信下载回来的文档都会出现标题所说的问题。 问题产生的原因&#xff1a; 初期在重装电脑后&#xff0c;将自带的一些安装系统后的第三方软件卸载掉了&#xff0c;也包括QQ浏览器。 可是在win11默认应用中看到了…

第五章SpringFramework之AOP

文章目录AOP概念及相关术语概述为什要用 AOP相关术语横切关注点Advice通知Join Point连接点Point CUT 切入点切面目标代理基于注解的SpringAOP准备工作切入点表达式语法重用切入点表达式对应的切面前置通知返回通知异常通知后置通知环绕通知切面的优先级总结Spring AOP 的实现步…

27.Isaac教程--局部建图

26.Isaac教程-局部建图 ISAAC教程合集地址: https://blog.csdn.net/kunhe0512/category_12163211.html 局部地图是机器人周围直接环境的基于网格的简化表示。 这些简化的世界表示对于安全地规划机器人附近的静态和动态障碍物至关重要。 局部建图管道将来自连接到机器人的不同传…

信息服务上线渗透检测网络安全检查报告和解决方案2(安装文件信息泄漏、管理路径泄漏、XSS漏洞、弱口令、逻辑漏洞、终极上传漏洞升级)

系列文章目录 信息服务上线渗透检测网络安全检查报告和解决方案 文章目录系列文章目录前言一、XSS漏洞漏洞危害解决方案1.参数过滤2.Cookie设置HttpOnly二、安装文件目录信息泄漏漏洞证明解决方案三、后台管理路径泄漏、暴力破解、明文传输漏洞证明解决方案四、逻辑漏洞漏洞验证…