函数说明
头文件
#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;
}