• system V共享内存


    共享内存的原理

    共享内存让不同进程看到同一份资源的方式就是,在物理内存当中申请一块内存空间,然后将这块内存空间分别与各个进程各自的页表之间建立映射,再在虚拟地址空间当中开辟空间并将虚拟地址填充到各自页表的对应位置,使得虚拟地址和物理地址之间建立起对应关系,至此这些进程便看到了同一份物理内存,这块物理内存就叫做共享内存。
    在这里插入图片描述

    共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据

    共享内存函数

    创建共享内存

    int shmget(key_t key, size_t size, int shmflg);
    
    • 1

    key:这个共享内存段名字

    size:共享内存大小

    shmflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的
    返回值:成功返回一个非负整数,即该共享内存段的标识码;失败返回-1

    如何创建key呢?

    key_t ftok(const char *pathname, int proj_id);
    
    • 1

    pathname:共享内存的路径
    proj_id:根据路径和id值生成key值

    shmflg说明

    IPC_CREAT:如果内核中不存在键值与key相等的共享内存,则新建一个共享内存并返回该共享内存的标识码;如果存在这样的共享内存,则直接返回该共享内存的标识码

    IPC_CREAT | IPC_EXCL:如果内核中不存在键值与key相等的共享内存,则新建一个共享内存并返回该共享内存的标识码;如果存在这样的共享内存,则出错返回

    删除共享内存

    int shmctl(int shmid, int cmd, struct shmid_ds *buf);
    
    • 1

    shmid:由shmget返回的共享内存标识码

    cmd:将要采取的动作(有三个可取值)

    buf:指向一个保存着共享内存的模式状态和访问权限的数据结构 返回值:成功返回0;失败返回-1

    cmd说明

    命令说明
    IPC_STAT把buf中的数据设置为共享内存的当期关联值
    IPC_SET在进程有足够权限的前提下,将共享内存的当前关联值设置为buf所指的数据结构中的值
    IPC_RMID删除共享内存段

    将共享内存段连接到进程地址空间

    void *shmat(int shmid, const void *shmaddr, int shmflg);
    
    • 1

    shmid: 共享内存标识

    shmaddr:指定连接的地址

    shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY

    返回值:成功返回一个指针,指向共享内存第一个节;失败返回-1

    将共享内存段与当前进程脱离

    int shmdt(const void *shmaddr);
    
    • 1

    shmaddr: 由shmat所返回的指针
    返回值:成功返回0;失败返回-1

    简单使用

    //comm.hpp
    #include
    #include
    #include
    #include
    #include
    
    using namespace std;
    #define PATH_IPC "/home/zjq/linuxl"
    #define PROJ_ID 0x114
    #define MAX_SIZE 4096
    
    key_t CreatKey()
    {
        key_t ret = ftok(PATH_IPC,PROJ_ID);
        return ret;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    //IpcShmCli.cpp
    #include"comm.hpp"
    
    int main()
    {
        key_t key = CreatKey();
        //创建共享内存
        int shmid = shmget(key,MAX_SIZE,IPC_CREAT | 0666);
        if(shmid<0)
        {
            cout<<"创建共享内存失败\n";
            return 1;
        }
        cout<<"客户端:创建共享内存成功"<<endl;
    
        //关联
        char* str = (char*)shmat(shmid,nullptr,0);
        if(str==nullptr)
        {
            cout<<"关联失败"<<endl;
        }
        cout<<"关联成功"<<endl;
    
        //使用
        for(int i=0;i<26;i++)
        {
            sleep(1);
            str[i]='A'+i;
            str[i+1]='\0';
        }
    
        //去关联
        shmdt(str);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    //IpcShmSer.cpp
    #include"comm.hpp"
    
    int main()
    {
        key_t key = CreatKey();
        //创建共享内存
        int shmid = shmget(key,MAX_SIZE,IPC_CREAT | IPC_EXCL | 0666);
        if(shmid<0)
        {
            cout<<"创建共享内存失败\n";
            return 1;
        }
        cout<<"服务器:创建共享内存成功"<<endl;
    
        char* str = (char*)shmat(shmid,nullptr,0);
        if(str==nullptr)
        {
            cout<<"关联失败"<<endl;
        }
        cout<<"关联成功"<<endl;
    
        //使用
        while(1)
        {
            sleep(1);
            cout<<str<<endl;
        }
    
        //去关联
        shmdt(str);
    
        //删除共享内存
        shmctl(shmid,IPC_RMID,nullptr);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    效果:
    在这里插入图片描述

    命令行查看共享内存与删除

    查看

    ipcs -m
    
    • 1

    在这里插入图片描述

    名称含义
    key系统标识各个共享内存
    shmid用户标识各个共享内存
    owner共享内存的所有者
    perms共享内存的权限
    bytes共享内存的大小
    nattch关联共享内存的进程数
    status共享内存的状态

    删除

    ipcrm -m shmid
    
    • 1

    在这里插入图片描述

  • 相关阅读:
    【Idea】idea、datagrip设置输入法
    专为医疗领域打造!飞凌嵌入式新一代FDU显控一体机发布
    Go--结构体
    手机怎么压缩图片?通过三种压缩操作
    云原生微服务治理经典框架之Spring Cloud Alibaba核心技术与实战案例
    AI时代你一定要知道的Agent概念
    CSS伪类选择器与浮动
    产品推荐 | 基于Anlogic系列EG4S20 FPGA开发板
    第8章 虚拟现实技术的相关软件
    Java开发之高并发必备篇(七)——线程池
  • 原文地址:https://blog.csdn.net/zjq_love/article/details/127707833