linux 共享内存(shm)的简单使用

函数说明

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

shmget
/* 创建共享内存
 * key:键,不同进程通过相同的键来获取同一个内存标识符
 * size: 申请的共享内存的空间大小
 * shmflg: IPC_CREAT(创建一个新的segment)  IPC_EXCL(与IPC_CREAT一起使用 确保一定创建了新的segment,如果存在新的segment则返回失败)
 * return: 成功时返回共享内存标识符,失败返回-1并设置errno
*/
int shmget(key_t key, size_t size, int shmflg);
shmat
/* 将shmid标识的共享内存段
 * shmid: shmget方法获取的标识符
 * shmaddr: 如果为NULL,则系统选择合适的页来创建共享内存
 * shmflg: SHM_RDONLY:只读  0:可读可写
 * return: 返回共享内存的地址
*/
void *shmat(int shmid, const void *shmaddr, int shmflg);
shmdt
/* 去关联共享内存
 * shmaddr:共享内存的地址
 * return: 正确返回0,错误返回-1并设置errno
*/
int shmdt(const void *shmaddr);
shmctl
/* performs the control operation specified by cmd on the System V shared memory segment whose identifier is given in shmid.
 * cmd: IPC_RMID(标记销毁相应的共享内存)等...
*/
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
查看申请的共享内存
# 查看申请的共享内存
ipcs -m
# 结果打印如下
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x120e0934 0          root       644        4096       1
0x00000000 32769      root       666        65536      1

简单使用

如果不同的进程可能会同时操作共享内存则需要进行加锁防止操作错误

通用方法封装
//.h
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define SHARED_MEM_FILE "/tmp/shared_mem"
#define SHARED_MEM_KEY 0x112
#define SHARED_SIZE 4096 * 1 //最好位页大小的整数倍

typedef struct SHM_S
{
	//内容根据需要自己写
	int a;
	char b;
	float c;
} SHM_S;
//使用之前判断是否为NULL
extern SHM_S* g_pSharedMem;

/* RDONLY 是否只读 1 只读, 0 可读可写 */
int IPC_SharedMem_Init(SHM_RDONLY_ENUM RDONLY);
int IPC_SharedMem_DeInit(void);
//cpp
SHM_S*          g_pSharedMem  = NULL;
int             g_sharedMemID = -1;
SHM_RDONLY_ENUM g_rdonly      = SHM_READ_ONLY;

int IPC_SharedMem_Init(SHM_RDONLY_ENUM RDONLY)
{
    g_rdonly = RDONLY;

    //首先创建 SHARED_MEM_FILE 这个文件
    int fd = -1;
    fd     = open(SHARED_MEM_FILE, O_RDWR | O_CREAT);
    if (fd < 0)
    {
        perror("fd :");
        return -1;
    }
    close(fd);

    key_t key = ftok(SHARED_MEM_FILE, SHARED_MEM_KEY); //生成key
    if (key < 0)
    {
        perror("ftok:");
        return -1;
    }
    g_sharedMemID = shmget(key, SHARED_SIZE, IPC_CREAT | 0644); //通过key创建出共享内存
    if (g_sharedMemID < 0)
    {
        perror("shmget:");
        return -1;
    }
    if (g_rdonly == SHM_READ_WRITE)
    {
        g_pSharedMem = (SHM_S*)shmat(g_sharedMemID, NULL, 0); //挂接共享内存 可读可写
    }
    else
    {
        g_pSharedMem = (SHM_S*)shmat(g_sharedMemID, NULL, SHM_RDONLY); //挂接共享内存 只读
    }
    if (g_pSharedMem == NULL)
    {
        return -1;
    }
    //初始化共享内存的数据
    //不加判断 在只读方式打开时会段错误
    if (RDONLY == SHM_READ_WRITE)
    {
        //初始化共享内存的值
        printf("[shm] init g_pSharedMem start\r\n");
        memset(g_pSharedMem, 0, sizeof(SHM_S));
        g_pSharedMem->pose.state           = 0;
        g_pSharedMem->pose.max_lAngleSpeed = -1;
        g_pSharedMem->pose.max_rAngleSpeed = -1;
        g_pSharedMem->gps.state            = GPS_STATE_ERROR;
    }

    return g_sharedMemID;
}
进程A

创建共享内存并对内存的值进行操作

//初始化共享内存
IPC_SharedMem_Init(SHM_READ_WRITE);
//写数据
if (g_pSharedMem != NULL){
	g_pSharedMem->a           = 1;
}

进程B

只读共享内存值 不写

//初始化
IPC_SharedMem_Init(SHM_READ_ONLY);
//读数据
if(g_pSharedMem != NULL){
	int a = g_pSharedMem->a;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值