共享内存允许两个或两个以上的进程共享同一存储区。因为数据不需要在客户进程与服进程之间来回复制,所以共享内存是进程间通信最快的方式。共享内存的通信模型如下图
共享内存仅在建立共享内存区域的时候需要内核的参与,一旦完成内存的开辟,所有访问操作可以视为对常规内存的访问,无需内核的参与。
共享内存的实现主要需要以下API
1、创建共享内存
int shmget(key_t key, size_t size, int shmflg);
2、挂载共享内存
void *shmat(int shmid, const void *shmaddr, int shmflg);
3、去关联共享内存
int shmdt(const void *shmaddr);
4、销毁共享内存
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
main.c
#include
#include
#include
#include
#include "shm.h"
void stop(int signum)
{
if (shm_exit()) {
printf("%s %s: shm_exit failed\n", __FILE__, __FUNCTION__);
}
exit(-1);
}
int main(int argc, char *argv[])
{
signal(SIGINT, stop);
if (shm_init()) {
printf("%s %s: shm_init failed\n", __FILE__, __FUNCTION__);
return -1;
}
while (1) {
sleep(3);
}
return 0;
}
shm.h
#ifndef __SHM_H__
#define __SHM_H__
int shm_init(void);
int shm_exit(void);
#endif
shm.c
#include
#include
#include
#include
#include
#include
#include "shm.h"
#define PATH_SHM "/tmp"
#define ID_SHM 100
#define SIZE_SHM 1024
static void *ptrShm = NULL;
static int g_shmid = 0;
static int shm_createShm(char *pathShm, int idShm, int size)
{
key_t key = ftok(pathShm, idShm);
printf("%s %s: key = %#x\n", __FILE__, __FUNCTION__, key);
int shmid = shmget(key, size, IPC_CREAT | IPC_EXCL | 0666);
if (shmid == -1) {
printf("%s %s: shmget failed\n",__FILE__, __FUNCTION__);
return -1;
}
// printf("%s: shmid = %#x\n", __FUNCTION__, shmid);
ptrShm = shmat(shmid, 0, 0);
if (ptrShm == (void *)-1) {
ptrShm = NULL;
printf("%s %s: shmat failed\n", __FILE__, __FUNCTION__);
return -1;
}
g_shmid = shmid;
return 0;
}
static int shm_destroyShm(void)
{
if (ptrShm) {
if (shmdt(ptrShm) == -1) {
printf("%s %s: shmdt failed\n", __FILE__, __FUNCTION__);
return -1;
}
if (shmctl(g_shmid, IPC_RMID, NULL) == -1) {
printf("%s %s: shmctl failed\n", __FILE__, __FUNCTION__);
return -1;
}
}
g_shmid = 0;
return 0;
}
int shm_init(void)
{
if (shm_createShm(PATH_SHM, ID_SHM, SIZE_SHM))
{
printf("%s %s: shm_createShm failed\n", __FILE__, __FUNCTION__);
return -1;
}
return 0;
}
int shm_exit(void)
{
if (shm_destroyShm())
{
printf("%s %s: shm_destroyShm failed\n", __FILE__, __FUNCTION__);
return -1;
}
return 0;
}