system V共享内存

共享内存的原理

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

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

共享内存函数

创建共享内存

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

key:这个共享内存段名字

size:共享内存大小

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

如何创建key呢?

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

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

shmflg说明

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

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

删除共享内存

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

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

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

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

cmd说明

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

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

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

shmid: 共享内存标识

shmaddr:指定连接的地址

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

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

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

int shmdt(const void *shmaddr);

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

简单使用

//comm.hpp
#include<sys/types.h>
#include<sys/ipc.h>
#include<iostream>
#include<sys/shm.h>
#include<unistd.h>

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;
}
//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;
}
//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;
}

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

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

查看

ipcs -m

在这里插入图片描述

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

删除

ipcrm -m shmid

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值