当前位置: 首页 > article >正文

【Linux:共享内存】

共享内存的概念: 

  • 操作系统通过页表将共享内存的起始虚拟地址映射到当前进程的地址空间中
  • 共享内存是由需要通信的双方进程之一来创建
  • 但该资源并不属于创建它的进程,而属于操作系统 
  • 共享内存可以在系统中存在多份,供不同个数,不同进程进行通信
  • 因此共享内存一定会存在一个数据结构来对共享内存进行管理
  • 共享内存=内存空间(数据)+共享内存的属性

共享内存的相关接口:

  • key:由用户形成,具有唯一性(内核区分shm的唯一性的),内核使用的一个字段,用户不能用Key来进行shm的管理
  • size:共享内存的大小
  • shmflg:标记位,可以用位图传参,认识它中的两个宏:IPC_CREAT和IPC_EXCL
  1. IPC_CREAT:创建的共享内存不存在就创建,存在则获取该共享内存并返回
  2. IPC_CREAT|IPC_EXCL:创建的共享内存不存在就创建,存在则出错返回
  3. IPC_EXCL:单独使用没有意义

共享内存不随着进程的结束就释放,因为共享内存不属于进程而属于操作系统,需要手动释放或者后续其它系统调用。共享内存的生命周期随内核。

查共享内存的命令:

ipcs -m

删除共享内存的命令:

ipcrm -m shmid

 

共享内存测试代码:

#ifndef __SHM_HPP__
#define __SHM_HPP__
#include <iostream>
#include <cerrno>
#include <cstdio>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
const std::string pathname = "/home/dl/pipe/shm";
int proj_id = 0x66;
const int Creater = 1;
const int User = 2;
const int CreatShmsize=4096;

class shm
{
private:
    // 获取共享内存
    int GetShmhelper(key_t key, int size, int flag)
    {
        int shmid = shmget(key, size, flag);
        if (shmid < 0)
        {
            perror("shmget");
        }

        return shmid;
    }
    //获取Key
    key_t GetcommKey()
    {
        key_t k = ftok(_pathname.c_str(), _proj_id);
        if (k < 0)
        {
            perror("ftok");
        }
        return k;
    }
private:
    key_t _key;
    int _shmid;
    std::string _pathname;
    int _proj_id;
    int _who;
public:
    shm(const std::string &pathname, int proj_id, int who)
        : _pathname(pathname),
        _proj_id(proj_id), 
        _who(who)
    {
        _key=GetcommKey();//获取共享内存都需要该参数,因此直接在构造时生成即可
        std::cout<<"shmid:"<<_shmid<<std::endl;
        std::cout<<"key:"<<TOHex(_key)<<std::endl;
        std::cout<<"who:"<<_who<<std::endl;
    }
    ~shm()
    {
        if(_who==Creater)
        {
            int res=shmctl(_shmid,IPC_RMID,nullptr);
            std::cout<<"shm remove done"<<std::endl;
        }
    }

    std::string TOHex(key_t key)
    {
        char buffer[128];
        snprintf(buffer, sizeof(buffer), "0x%x", key);
        return buffer;
    }
    bool GetShmCreater()
    {
        //判断是否为创建者
        if(_who==Creater)
        {
           int shmid = GetShmhelper(_key,CreatShmsize,IPC_CREAT|IPC_EXCL);
           if(shmid>0)
            std::cout<<"shm creat done"<<std::endl;
            sleep(5);
           return true;
        }
        return false;
    }
    bool GetShmUse()
    {
         //判断是否为使用者
        if(_who==User)
        {
           int shmid = GetShmhelper(_key,CreatShmsize,IPC_CREAT);
           if(shmid>0)
            std::cout<<"shm get done"<<std::endl;
           return true;
        }
        return false;
    }


};

#endif


 


http://www.kler.cn/a/316365.html

相关文章:

  • Ceph 中PG与PGP的概述
  • JAVA:探索 EasyExcel 的技术指南
  • Spring-Webflux + Reactor + Netty 初体验
  • 基于微信小程序的乡村研学游平台设计与实现,LW+源码+讲解
  • 数据集标注txt文件读取小工具
  • MybatisPlus入门(十)MybatisPlus-逻辑删除和多记录操作
  • C# 从字符串中分离文件路径、文件名及扩展名
  • C# winforms DataGridView设置数据源自动显示表格
  • Go 第二期
  • 界面控件Telerik UI for WinForms 2024 Q3概览 - 支持合并单元格等
  • (已解决)vscode如何选择python解释器
  • 【学习笔记】SSL/TLS安全机制之HSTS
  • apt-get install 安装的tomcat配置
  • biopython提取.cif文件的变换矩阵
  • spring全家桶使用教程
  • Kotlin 操作符 in 的基本使用(十)
  • docker存储
  • 2.《DevOps》系列K8S部署CICD流水线之部署NFS网络存储与K8S创建StorageClass
  • 2016年国赛高教杯数学建模A题系泊系统的设计解题全过程文档及程序
  • Python基础学习(3)
  • SpinalHDL之结构(二)
  • rabbitmq整合skywalking并编写自定义插件增强
  • 超详图解 Apache HTTP Server(httpd)安装与验证
  • 设计模式 享元模式(Flyweight Pattern)
  • 『功能项目』QFrameWorkBug修改器界面【65】
  • 数据结构(十四)——HashMap与HashSet(OJ题)