linux -- System V 共享内存

一、相关函数

  • 头文件
#include <sys/ipc.h>
#include <sys/shm.h>

1.1、shmget :创建共享内存

int shmget(key_t key, size_t size, int shmflg);
  • key:创建共享内存的关键字
    IPC_PRIVATE:创建新的共享内存
    或者由 ftok 函数产生
    或者自定义一个key
  • size:设定共享内存的大小
  • shmflg:共享内存的访问权限
    0 访问已存在的IPC
    IPC_CREAT | 0644:不存在则创建新的IPC
    IPC_EXCL和IPC_CREAT一起用 判断IPC是否存在
  • 返回值
    >0 共享内存ID ,类似文件描述符
    -1 出错

1.2、shmat:映射共享内存

void *shmat(int shmid, const void *shmaddr, int shmflg);
  • shmid:共享内存的id号
  • shmaddr:指定共享内存在当前进程中的地址,通常为NULL
  • shmflg:共享内存的使用权限
    SHM_RDONLY:以只读的方式使用此内存段
    其他:以读写的方式
  • 返回值
    >0 共享内存的首地址
    -1 失败

1.3、 shmdt:解除映射

int shmdt(const void *shmaddr);
  • addr:调用shmat时返回的共享内存首地址
  • 返回值
    0 成功
    -1 失败

1.4、shmctl:对共享内存的一些操作

int shmctl(int shmid, int cmd, struct shmid_ds *buf);
  • shmid:共享内存的id号
  • cmd:对共享内存的操作
    IPC_RMID :删除共享内存段
    IPC_STAT:获取shmid_ds结构,并将其放在由buf指向的结构中
    IPC_SET:按buf指向结构中的值设定此段相关结构中的一些内容
    SHM_LOCK:将共享内存锁定在内存中
    SHM_UNLOCK:解锁
  • buf :设置共享内存时需要的数据或接收共享内存属性的内存地址
    删除共享内存时可以为NULL

二、简单应用

  1. 共享内存不依赖与进程而存在(只要不主动删除,进程退出了,共享内存还在)
  2. 键key可以自己指定(>0),也可以通过ftok生成
  3. 可以通过shmid再次访问共享内存
  4. 键>0 和 shmid 都是全局唯一的
  5. 键为IPC_PRIVATE 时 = 0,不能通过此键访问共享内存,只会创建
  6. 对于不同的进程
    同一个key,shmget()返回的id一样
    同一个shmid,shmat()返回的地址一样
  7. 可以同时读写共享内存

2.1、 不关联文件:读/写

#include <stdio.h>
#include <stdlib.h>
#include <sys/shm.h>

#define KEY 10//只要不和已有的一样,可任意设置
int main() {
    int id;
    char *buf;
	//创建共享内存 大小为1024
    id = shmget(KEY,1024,IPC_CREAT | 0644);
    if(id == -1){
        perror("shmget");
        exit(1);
    }
    printf("id = %d\n", id);
	//映射共享内存
    buf = (char *) shmat(id,NULL,0);
    printf("buf :  %p\n",buf);

	//写程序
    for(int i = 0;i<10;i++){
        buf[i] = (char)('a'+i);
    }
    printf("write :   %s\n",buf);
    //读程序
    //printf("read :   %s\n",buf);

    shmdt(buf);//取消映射
    //shmctl(id,IPC_RMID,NULL);//删除共享内存
    return 0;
}

在这里插入图片描述

  • 使用ipcs命令查看共享内存
$ ipcs

在这里插入图片描述
key = 0x0000000a 换算成十进制就是 10
shmid =10 是按最小可用来分配的

  • 加 IPC_EXCL再执行write / 删除 IPC_EXCL再执行write
  • ipc对象只能由一方创建
    在这里插入图片描述

2.2、 关联文件:读/写

#include <stdio.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <unistd.h>

#define PATH "./shm" //设置共享内存要关联的文件
#define Proj_Id 16 //只要不和已有的一样,可任意设置

typedef struct {
    char msg[10];
    int num;
}Data;

int main() {
    int key,shm_id,size;
    Data *buf;

     /*将关联文件转化为key */
    key = ftok(PATH,Proj_Id);
    if(key == -1){
        perror("ftok");
        exit(1);
    }
    //也可以不关联文件,自己设置key的值
    // key = 16; //只要不和已有的一样,可任意指定
    printf("key = %d\n",key);

    /*创建共享内存 大小为size */
    size = sizeof(Data)*10;
    printf("size = %d\n",size);
    shm_id = shmget(key, size,IPC_CREAT | 0644);
    if(shm_id == -1){
        perror("shmget");
        exit(1);
    }
    printf("shm_id = %d\n", shm_id);

    /*映射共享内存 */
    buf = (Data *) shmat(shm_id,NULL,0);
    printf("buf :  %p\n",buf);

    printf("开始写入:\n");
    for(int i = 0;i<10;i++){
    	//注释下面两行即可变成读程序
        (buf+i)->msg[0] = (char)('a'+i);
        (buf+i)->num = i+1;
        
        printf("num = %d,  msg = %s \n",(buf+i)->num, (buf+i)->msg);
        sleep(1);
    }
    printf("写入结束:\n");
    shmdt(buf);
    return 0;
}

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

2.3、shell命令创建/删除共享内存

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值