目录
共享内存区是最快的IPC 形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到操作系统内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据,操作系统内核中会存在多个共享内存块,操作系统也会为每个共享内存块创建对应的描述该块内存的数据结构体对象,这样操作系统就可以管理这些共享内存块了!
在Linux中可以通过指令:ipcs -m 查看内核中的共享内存,使用指令ipcrm -m shmid 删除共享内存。
共享内存函数
头文件
共享内存函数的头文件都是sys/shm.h
shmget
功能:用来创建共享内存
int shmget(key_t key, size_t size, int shmflg);
参数:
key: 这个共享内存段名字关于key值的解释:1.key值其实是内核里描述共享内存块的结构体中的一个值,该值用于标识不同的共享内存块。
2.第一个进程通过key值创建共享内存,第二个进程只要使用相同的key就可以和第一个进程看到相同的共享内存块了。3.key值可以通过ftok函数得到,如下:ftok函数
返回值:shmget函数中的参数key
size:共享内存大小(单位是byte)
shmflg:由九个权限标志构成,它的用法和创建文件时使用的 mode 模式标志是一样的IPC_CREAT(单独使用):表示如果要申请共享内存(内核会根据用户调用shmget传入的参数key值与内核中存在的key匹配,通过匹配确定该共享内存是否存在)不存在就创建,存在就获取该共享内存。IPC_CREAT|IPC_EXCL:如果要申请的共享内存不存在,就创建;存在就错误返回,因此该参数组合申请的共享内存必定是新的!
返回值:
成功返回一个非负整数,即该共享内存段的标识码(shmid);失败返回-1
shmat
功能:将共享内存段连接到进程的地址空间
void *shmat(int shmid, const void *shmaddr, int shmflg);
参数
shmid:
共享内存标识
shmaddr:指定连接的地址 (一般为nullptr,即由内核将该共享内存段连接到进程地址空间里的共享区)
shmflg:
它的两个可能取值是
SHM_RND
和
SHM_RDONLY
返回值:成功返回一个指针(进程地址空间的共享区中的这块共享内存的
起始虚拟地址
),指向共享内存中第一个字节的地址;失败返回
-1
shmdt
功能:将共享内存段与当前进程脱离
int shmdt(const void *shmaddr);
参数:
shmaddr: 由shmat所返回的指针
返回值:成功返回
0
;失败返回
-1
注意:将共享内存段与当前进程脱离不等于删除共享内存段
shmctl
功能:用于控制共享内存
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数
shmid:
由
shmget
返回的共享内存标识码
cmd:
将要采取的动作(有三个可取值)
![](https://i-blog.csdnimg.cn/direct/591a4cd8bcc74597a9fdcd17913e9fba.png)
buf:
指向一个保存着共享内存的模式状态和访问权限的数据结构
返回值:成功返回
0
;失败返回
-1
#pragma once
#include <iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <cstdlib>
#include <cstdio>
#define PATHNAME "/home/kk"
#define MODE 0x777
#define SIZE 4096
key_t GetKey() //创建一个key值
{
key_t key =ftok(PATHNAME, MODE);
if(key<0)
{
perror("ftok:");
exit(1);
}
return key;
}
int CreateShmHelper(int flag)
{
int shmid = shmget(GetKey(), SIZE, flag);
if(shmid<0)
{
perror("shmget:");
exit(2);
}
return shmid;
}
int CreateShm()
{
return CreateShmHelper(IPC_CREAT|IPC_EXCL);
}
int GetShm()
{
return CreateShmHelper(IPC_CREAT);
}