1.提问
1.什么是共享内存?
2.使用环境(用来解决什么问题)是什么?
3.接口是什么样的?如何使用?
2.什么是共享内存?
1. 两个或多个进程共享物理内存的同一块区域(通常被称为段)。由于一个共享内存段会成为一个进程用户空间内存的一部分,因此这种IPC机制无需内核介入。所有需要做的就是让一个进程将数据复制进共享内存中,并且这部分数据会对其他所有共享同一个段的进程可用。
2. 优点:与管道或消息队列区别:管道或消息队列要求 a.发送进程将数据从用户空间的缓冲区复制进内核内存。 b.接收进程将数据从内核内存复制进用户空间的缓冲区。
而共享内存无需内核介入,所以共享内存技术速度更快。
3. 缺点:用户同时访问共享内存,会导致数据出错。
对应策略:通过某些同步方法使得不会出现上述情况,例如:System V信号量,POSIX信号量,文件锁。
4. 基本操作有:创建,打开,附上,分离,控制(删除)。
创建和打开——shmget()——shared memory get
附上——shmat()——shared memory attach
分离——shmdt()——shared memory detach
控制(删除)——shmctl()——shared memory control
[共享内存函数——百度百科](https://baike.baidu.com/item/shmctl/5391631?fr=aladdin)
3.接口细节?
//头文件
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
key_t ftok(const char* pathname, int proj_id);
用于创建一个关键字,该关键字关联一个共享内存段
调用成功返回一个关键字,失败返回-1.
pathname 为全路径文件名,且该文件必须可以访问
proj_id 通常为一个非0的数字
通过上面两个的组合可以创建唯一的key值。(也就是对应唯一的共享内存段)
int shmget(key_t key, int size, int shmflg);
用于创建或打开一个共享内存段,该共享内存段由key唯一创建。
成功返回唯一的共享内存标识号,失败返回-1 。
key
1用ftok产生,
2由IPC_PRIVATE(用于创建一个只属于创建进程的共享内存,主要用于父子进程间通信),表示总是创建新的内存。
size
指定共享内存的大小,以字节为单位。
shmflg
是一掩码合成值,可以设置为IPC_CREAT和IPC_EXCL和访问权限值(如0600)的合成。
IPC_CREAT表示创建该共享内存,如果已存在,则返回该共享内存标识号。
IPC_CREAT和IPC_EXCL一同使用,则如果该key对应的共享内存已存在,则调用失败,返回-1 。如果不存在,则创建,返回该共享内存标识号。
void* shmat(int shmid, const void* shmaddr, int shmflg);
将共享内存段映射到进程空间的某一地址。
如果调用成功,则返回映射后的进程空间首地址,失败返回(char*)-1 。
shmid 共享内存标识符,一般为shmget调用成功后的返回值。
shmaddr 指定共享内存映射到进程空间的地址(也就是你想把共享内存放在你进程空间的哪里)
一般为NULL,表示让系统来选择映射的地址
shmflg 为一组位标识,通常为0。
如果映射失败,可能是shmget时权限设置不对,如没设置0600 。
int shmdt(const void* shmaddr);
用于共享段和进程地址空间分离。(注意不是删除)
成功返回0,失败返回-1 。
shmaddr 通常为共享内存首地址,也就是shmat的返回值。
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
执行成功,返回0,标记删除成功。只有当最后一个进程解除连接,共享内存段才会被删除。
共享内存的控制函数,可以用来删除共享内存段
shmid 共享内存标识符
cmd 指令
IPC_STAT
IPC_SET
IPC_RMID 表示删除共享内存段
buf 表示共享内存段的信息结构体数据,通常为NULL
4.使用环境(用来解决什么问题)是什么?
1.大页
2.进程间通信