C语言笔记-23-Linux基础-共享内存

C语言笔记-23-Linux基础-共享内存



前言

自学笔记,没有历史知识铺垫(省略百度部分)C语言笔记-23-Linux基础-共享内存


一、共享内存概括

ipcs指令

查询当前系统的共享队列、共享内存、共享信号量。

dony15$ ipcs
IPC status from <running system> as of Mon Dec 12 22:02:49 CST 2022
T     ID     KEY        MODE       OWNER    GROUP
Message Queues:

T     ID     KEY        MODE       OWNER    GROUP
Shared Memory:

T     ID     KEY        MODE       OWNER    GROUP
Semaphores:
s  65536 0x0b042e74 --ra-ra-ra-     root    wheel
s  65537 0x0b040ced --ra-ra-ra-   dony15    staff
s  65538 0x250421fb --ra-ra-ra-   dony15    staff
s  65539 0x0b046aab --ra-ra-ra-   dony15    staff

共享内存使用流程

1. 生成键值

使用path和id生成一个system v ipc的键值
key_t ftok(const char *path, int id);

参数

path 指定一个有效的路径名
id 指定一个非0的整数 使用这个整数的低有效8bit
返回值:
成功:返回一个键值
失败: -1 errno被设置

2. 使用健值获取共享内存变量id

分配一个system v 共享内存段
int shmget(key_t key, size_t size, int shmflg);

参数

key 返回跟这个key值相关的共享内存段的id
size 指定了共享内存段的大小
shmflg

  1. IPC_CREAT 如果没有跟key值相关的共享内存段,则创建共享内存段.否则只检查访问权限
  2. IPC_EXCL IPC_EXCL和IPC_CREAT一起使用时,共享内存段已经存在时报错

注意:shmflg|权限控制符 将指定共享内存段操作权限,如IPC_CREAT | 0644

返回值

成功:返回共享内存段的id
错误: -1 errno被设置

3. 将共享内存对象关联到进程地址空间中

将共享内存段关联到当前进程的地址空间
void * shmat(int shmid, const void *shmaddr, int shmflg);

参数

shmid 指定了具体的共享内存段
shmaddr 指定了关联的地址(当前进程的地址) NULL 由系统选择地址
shmflg 0

返回值

成功:返回关联到进程的地址
错误: -1 errno被设置

4. 操作内存空间

do Some...

5. 解除共享内存对象关联

解除共享内存段和进程的关联
int shmdt(const void *shmaddr);

参数

shmaddr 指定共享内存段关联到进程的地址

返回值

成功:返回0
错误: -1 errno被设置

二、共享内存代码示例

示例代码

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

int main(int argc, char *argv[])
{
    // 返回一个键值 key
    key_t key = ftok(argv[1], 13);
    if (key == -1)
    {
        perror("创建共享内存失败");
    }
    printf("key 0x%x\n", key);

    // 返回共享内存对象ID
    int shmId = shmget(key, 1024, IPC_CREAT | 0644);
    if (shmId == -1)
    {
        perror("获取共享内存ID失败");
    }
    printf("shmId %d\n", shmId);

    // 将共享内存段关联到当前进程的地址空间
    void *p_shm = shmat(shmId, NULL, 0);
    if (p_shm == (void *)-1)
    {
        perror("将共享内存段关联到当前进程的地址空间失败");
    }

    // 操作共享内存对象
    strcpy(p_shm, "TATATA");
    printf("p_shm %s\n", p_shm);
    strcpy(p_shm, "TATATA2");
    printf("p_shm %s\n", p_shm);

    // 解除共享内存对象关联
    int dt = shmdt(p_shm);
    if (dt == -1)
    {
        perror("解除共享内存对象关联失败");
    }

    return 0;
}

执行结果

dony15$ ./main abc.test
key 0xd043784
shmId 196608
p_shm TATATA
p_shm TATATA2

dony15$ ipcs -m -a
IPC status from <running system> as of Mon Dec 12 23:10:39 CST 2022
T     ID     KEY        MODE       OWNER    GROUP  CREATOR   CGROUP NATTCH  SEGSZ  CPID  LPID   ATIME    DTIME    CTIME
Shared Memory:
m 196608 0x0d043784 --rw-r--r--   dony15    staff   dony15    staff      0   1024   6630   9012 23:09:00 23:09:00 22:50:20

总结

本章主要为C语言笔记-23-Linux基础-共享内存

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值