0基础学会共享内存(内附源码)

目录

一、与共享内存相关的函数

1、shmget()函数的使用:

2、shmat()函数的使用

3、shmdt()函数的使用

4、shmctl()函数的使用

5、ftok()函数的使用

6、接下来用代码解释这些函数的意思:

二、共享内存中出现的问题

三、共享内存和内存映射的区别:

一、与共享内存相关的函数

1、shmget()函数的使用:

#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

-返回值:

失败:返回-1,并设置错误号

成功:>0,返回共享内存引用的ID,后面操作共享内存都是通过这个值。

2、shmat()函数的使用

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

-功能:和当前的进程相关联

-参数:

-shmid:共享内存的标识(ID),由shmget返回值获取。

-shmaddr:申请的共享内存起始位置,指定NULL,内核指定;

-shmflg:对共享内存的操作

                -读:SHM_RDONLY,必须要有读权限

                -读写:0

-返回值:

        成功:返回共享内存的首(起始)地址。失败(void *)-1.

3、shmdt()函数的使用

int shmdt(const void *shmaddr);

-功能:解除当前进程和共享内存的关联

-参数:

        shmaddr:共享内存的首地址

-返回值:成功0,失败-1

4、shmctl()函数的使用

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

-功能:删除共享内存,共享内存要删除才会消失,创建共享内存的将进行被销毁了

-参数:

        -shmid:共享内存的ID

        -cmd:要做的操作

                -IPC_STAT:获取共享内存的当前状态

                -IPC_SET:设置共享内存的状态

                -IPC_RMID:标记共享内存被销毁

        -buf:需要设置或者获取的共享内存的属性信息

                -IPC_STAT:buf存储数据

                -IPC_SET:buf中需要初始化数据,设置到内核中

                -IPC_RMID:没有用,NULL;

5、ftok()函数的使用

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

-功能:根据指定的路径名,和int值,生成一个共享内存的key;

-参数:

        -pathname:指定一个存在的路径

        /home/shirui/Desktop/shared/a.txt

        -proj_id:int 类型的值,但是这系统调用只会使用1个字节

                        范围:0-255 一般指定一个字符'a'。

6、接下来用代码解释这些函数的意思:

首先往内存中写数据

//写
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
int main()
{
    //1、创建共享内存
    int shmid=shmget(100,1024,IPC_CREAT|0664);
    //2、关联当前进程
    void (*ptr)=shmat(shmid,NULL,0);
    //3、往内存中写数据
    char *buf="hello guy";
    memcpy(ptr,buf,strlen(buf)+1);//将buf中的内容复制到ptr这个首地址中去,别忘了字符串的长度+1

    printf("按一下继续!\n");
    getchar();
    //4、解除关联
    shmdt(ptr);
    //5、删除共享内存
    shmctl(shmid,IPC_RMID,NULL);
    return 0;
}

紧接着去内存中读数据:

//去内存中读取数据
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
int main()
{
    //1、创建共享内存
    int shmid=shmget(100,1024,IPC_CREAT);
    //2、关联当前进程
    void (*ptr)=shmat(shmid,NULL,SHM_RDONLY);
    //3、读取内存中的数据
    printf("%s\n",(char *)ptr);

    printf("按一下继续!\n");
    getchar();
    //4、解除关联
    shmdt(ptr);
    //5、删除共享内存
    shmctl(shmid,IPC_RMID,NULL);
    return 0;
}

 执行写文件:

 执行读文件:

 

二、共享内存中出现的问题

问题1:操作系统如何知道一块共享内存被多少个进程关联?

-共享内存维护了一个结构体struct shmid_ds 这个结构体成员中有一个成员shm_nattach

-shm_nattach记录了关联的进程个数

问题2 :可以对共享内存进行多次删除shmctl嘛?

可以的,因为shmctl标记删除共享内存,不是直接删除

-什么时候真正删除呢?

当和共享内存关联的进程数为0的时候就真正被删除。

-当共享内存的key为0的时候,表示共享内存被标记删除了

如果一个进程和共享内存取消关联,那么这个进程就不能继续操作这个共享内存了。

三、共享内存和内存映射的区别:

1、共享内存可以直接创建,内存映射需要磁盘文件(匿名映射除外)

2、共享内存效率更高;

3、内存

        所有的进程操作都是对同一块共享内存;

        内存映射,每个进程在自己的虚拟地址空间中有一个独立的内存

4、数据安全

        -进程突然退出

                共享内存还存在

                内存映射区消失

        -运行进程的电脑死机、宕机了

                数据存在共享内存中,没有了

                内存映射区的数据,由于磁盘文件中的数据还在,所以内存映射区的数据还存在

5、生命周期

                -内存映射区:进程退出,内存映射区销毁

                -共享内存:进程退出,共享内存还在,标记删除(所有的关联进程数为0),或者关机

                如果一个进程退出,会自动和共享内存进行取消关联。

以上就是关于共享内存的相关说明。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值