标签:共享内存
什么是共享内存?
共享内存就是允许两个不相关的进程访问同一块物理内存。进程可将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址。如果某一个进程向共享内存中写入数据,所做的改动将立即影响到可以访问同一段共享内存的其他进程。
函数接口
(1)创建共享内存
函数原型:int shmget(key_t key,size_t size,int shmflg)
key :由ftok()函数返回的标识符
size:以字节为单位的需要共享的内存容量
shmflg:
IPC_CREAT:单独使用,若共享内存不存在,创建,否则,直接打开。
IPC_EXCL:单独使用无意义
IPC_CREAT | IPC_EXCL:若不存在,创建,否则返回-1.
(2)对共享内存的访问
函数原型:void *shmat(int shm_id,const void* shm_addr,int shmflg)
shm_id:是shmget函数返回的标识符
shm_addr:指定共享内存连接到当前进程中的地址位置,通常为NULL,表示让系统来选择共享内存的地址
shm_flg:IPC_CREAT或为0
返回值:成功时返回指向共享内存的指针,失败返回-1.
(3)将共享内存从当前过程中分离
函数原型:int shmdt(const void* shmaddr)
shmaddr:shmat函数的返回值
返回值:成功返回0,失败返回-1.
(4)控制内存共享
函数原型:int shmctl(int shm_id,int cmd,struct shmid_ds* buf)
shm_id: shmget函数返回的标识符
cmd:
IPC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值,即用共享内存的当前关联值覆盖shmid_ds的值。
IPC_SET:如果进程有足够的权限,就把共享内存的当前关联值设置为shmid_ds结构中给出的值
IPC_RMID:删除共享内存段
“shm.h”
“shm.c”
“test.c”
运行结果:
结果分析: 每隔一秒打印root的共享内存的情况。
首先由父进程创建共享内存,父进程创建子进程,父子进程都关联了共享内存,关联的个数由0变为2,因父进程休息时间短,取消关联,关联个数变为1,最后子进程也取消关联,关联个数变为0,最后将共享内存destory。。。
3.mmap函数
mmap将一个文件或者其他对象映射进内存。mmap也可以实现共享内存。mmap函数调用使得进程之间通过映射同一个文件实现共享内存。文件被映射到进程地址空间后,进程可以像读写内存一样对文件进行操作。
函数原型:void* mmap(void* addr,size_t length,int prot,int flags,int fd,off_t offset);
addr:映射区的开始地址,设置为0时表示系统决定映射区的起始地址
length:映射区的长度。长度单位为字节
prot:期望的内存保护标志。取以下几个值:
PORT_EXEC:页内容可以被执行 PORT_READ:页内容可以被读取
PORT_WRITE:页内容可以被写入 PROT_NONE:页内容不可访问
flag:指定映射对象的类型,映射选项与映射页是否可以共享。
MAP_SHARED:与其他所有映射这个对象的进程共享映射空间。
MAP_PRIVATE:建立一个写入时拷贝的私有映射。内存区域的写入不会影响到原文件。
MAP_FIXED :使用指定的映射起始地址,如果由start和len参数指定的内存区重叠于现存的映射空 间,重叠部分将会被丢弃。如果指定的起始地址不可用,操作将会失败。
fd: 有效的文件描述符。返回,由一般open()函数,其值可以设置为-1.此时需要指定flags参数为 MAP_ANON,表明进行的是匿名映射。
offset:被映射对象内容的起点。
返回值:成功,返回被映射区的指针;失败,返回-1.
本文出自 “一起去看星星” 博客,转载请与作者联系!
标签:共享内存
原文地址:http://10810429.blog.51cto.com/10800429/1829439