Linux:共享内存

共享内存(效率最高的进程间通信方式)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

共享内存简单实现

/*
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
-功能:创建一个新的共享段,或者获取一个既有的共享内存段的标识
       新创建的内存段中的数据都会被初始化为0
-参数:
    -key:       key_t是整形,通过这个找到或者创建一个共享内存,一般使用16进制的非0值
    -size:      也是个整形,共享内存的大小,分页的整数倍
    -shmflg:   属性:访问权限/附加属性:创建/判断共享内存是否存在
                    -IPC_CREAT:创建
                    -IPC_EXCL: 判断共享内存是否存在,需要和IPC_CREAT一起使用(IPC_CREAT | IPC_EXCL | 0664)
                    -SHM_HUGETLB:不常用
                    -SHM_HUGE_2MB:不常用

-返回值:
    -成功: >0的值,表示共享内存引用的ID
    -失败: -1,并且设置错误号

===============================================================================================================\
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
-功能:和当前的进程进行关联
-参数:
    -shmid:共享内存的标识ID,即shmget的返回值
    -shmaddr:申请的共享内存的起始地址,指定NULL,由内核指定。
    -shmflg:对共享内存的操作
        -不指定(0):读写
        -SHM_EXEC:
        -SHM_RDONLY:读,必须要有读权限
        -SHM_REMAP:

-返回值:
    -成功:返回共享内存的首地址
    -失败:(void *)-1;

int shmdt(const void *shmaddr);

===============================================================================================
#include <sys/types.h>
#include <sys/shm.h>
int shmdt(const void *shmaddr);
-功能: 解除当前进程和共享内存的关联
-参数:
    -shmaddr:共享内存的首地址
-返回值:
    -成功:0
    -失败:-1

==============================================================================================
#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
-功能:操作共享内存,共享内存要删除才消失,创建共享内存的进程被销毁了对共享内存没有影响
-参数:
    -shmid:共享内存的ID
    -cmd: 要做的操作
        -IPC_STAT:获取共享内存当前的状态
        -IPC_SET: 设置共享内存的状态
        -IPC_RMID: 标记共享内存被销毁
    -buf:需要设置或者获取的共享内存的属性信息
        -IPC_STAT:buf存储数据
        -IPC_SET: buf中需要初始化数据,设置到内核中
        -IPC_RMID: 没有用(NULL)


*/

#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>

int main(){
    //创建共享内存
    int shmID = shmget(100, 4096, IPC_CREAT|0664);
    printf("shmID = %d\n", shmID);
    if(shmID == -1){
        perror("shmget");
        return -1;
    }

    //关联
    void *addr = shmat(shmID, NULL, 0);
    if(addr == (void *)-1){
        perror("shmat");
        return -1;
    }

    //进行操作:写数据
    char buff[1024] = "hello this is share A \n";
    memcpy(addr, buff, sizeof(buff));
    printf("按任意键继续 \n");
    getchar();

    //解除关联
    shmdt(addr);

    //删除共性内存
    shmctl(shmID, IPC_RMID, NULL);


    return 0;
}

#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>

int main(){
    //创建共享内存
    int shmID = shmget(100, 0, IPC_CREAT);
    printf("shmID = %d\n", shmID);

    if(shmID == -1){
        perror("shmget");
        return -1;
    }

    //关联
    void *addr = shmat(shmID, NULL, 0);
    if(addr == (void *)-1){
        perror("shmat");
        return -1;
    }

    //进行操作:读数据
    printf("%s",(char*)addr);

    printf("按任意键继续。。。。。。\n");
    getchar();

    //解除关联
    shmdt(addr);

    //删除共性内存
    shmctl(shmID, IPC_RMID, NULL);


    return 0;
}

相关问题

/*
问题1: 操作系统如何知道一块共享内存被多少个进程关联?
    -共享内存维护了一个结构体struct shmid_ds这个结构体中有一个成员shm_attch记录了关联的进程个数
        -共享内存的键变为0表示标记删除,因为还有进程和他关联,当没有进程关联时删除

问题2:是否可以对共享内存进行多次删除shmctl
    -可以,shmctl是标记删除,只有当关联数为0时才被真正删除

问题3:共享内存和内存映射的区别
    -共享内存可以直接创建,内存映射需要磁盘文件(匿名映射除外)
    -共享内存效率更高
    -内存:
        -共享内存:所有的进程操作的是同一块内存
        -内存映射:每个进程在自己的虚拟地址空间中有一个独立的内存
    -数据安全:
        -进程突然退出:
            -共享内存还存在
            -内存映射区消失
        -运行进程的电脑死机:
            -数据存储在共享内存中就没了
            -内存映射区中的数据由于磁盘文件中的数据还在,所以内存映射区的数据还存在
    -生命周期:
        -共享内存:进程退出,共享内存还在,手动删除(所有的关联都没了)或者关机才销毁
                  如果一个进程退出,会自动和共享内存取消关联。
        -内存映射:进程退出,内存映射区销毁


*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值