Linux共享内存

共享内存

共享内存可以通过mmap()映射普通文件

使一个磁盘文件与内存中的一个缓冲区相映射,进程可以像访问普通内存一样对文件进行访问,不必再调用read,write。

#include <sys/mman.h>
void *mmap(void *addr,size_t length,int prot,int flags,int fd,off_t offset);

注意事项:

创建映射区的过程中,隐含着一次对映射文件的读操作,将文件内容读取到映射区。

当MAP_SHARED时,要求:映射区的权限应<=文件打开的权限(出于对映射区的保护),如果不满足报非法参数(Invalid argument)错误。当MAP_PRIVATE时候,mmap中的权限是对内存的限制,只需要文件有读权限即可,操作只在内存有效,不会写到物理磁盘,且不能在进程间共享。

映射区的释放与文件无关,只要映射建立成功,文件可以立即关闭。

用于映射的文件大小必须>0,当映射文件大小为0时,指定非0大小创建映射区,访问映射地址会报总线错误,指定0大小创建映射区,报非法参数错误(Invalid argument)

文件偏移量必须为0或者4K的整数倍(不是会报非法参数Invalid argument错误)

映射区大小可以大于文件大小,但只能访问文件page的内存地址,否则报总线错误,超出映射的内存大小报段错误

mmap()映射的种类:

基于文件的映射

匿名映射:适用于具有亲缘关系的进程之间

释放内存映射

int munmap(void *addr,size_t length);

测试代码

写内存cpp

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stddef.h>
#include <string.h>
#include <sys/mman.h>
int main(){
	void *addr;
	int fd;
	fd=open("test",O_RDWR);
	int len=lseek(fd,0,SEEK_END);
	addr=mmap(NULL,2048,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
	if(addr==MAP_FAILED){
		perror("mmap");
		return 0;
	}
	close(fd);
	int i=0;
	while(i<2048){
		memcpy((addr+i),"a",1);
		i++;
		sleep(1);
	}
    munmap(addr,2048);
	return 0;
}

 读内存cpp

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stddef.h>
#include <string.h>
#include <sys/mman.h>
int main(){
	void *addr;
	int fd;
	fd=open("test",O_RDWR);
	int len=lseek(fd,0,SEEK_END);
	addr=mmap(NULL,2048,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
	if(addr==MAP_FAILED){
		perror("mmap");
		return 0;
	}
	close(fd);
	int i=0;
	while(1){
		printf("read=%s\n",(char*)addr);
		sleep(1);
	}
    munmap(addr,2048);
	return 0;
}

测试结果

 

system V共享内存

文件生成key值--ftok

#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *path,int proj_id);

成功时返回合法的key值,失败时返回EOF。

path 存在且可访问的文件的路径。

proj_id 用于生成key的数值,1-255。

共享内存创建--shmget

#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key,int size,int shmflg);

成功时返回合法的key值,失败时返回EOF。

key 和共享内存关联的key,IPC_PRIVATE或者ftok生成。

shmflg 共享内存标志位 IPC_CREATE|0666

共享内存映射--shmat

void *shmat(int shmid,const void *shmaddr,int shmflg);

成功时返回映射后的地址,失败时返回(void*)-1。

shmid 要映射的共享内存的id

shmaddr 映射后的地址,NULL表示系统自动映射

shmflg 标志位 0表示可读写;SHM_RDONLY表示只读

共享内存撤销映射--shmdt

int shmdt(void* shmaddr);

成功时返回0,失败时返回EOF

不使用共享内存时应撤销映射

进程结束时自动撤销

 

共享内存控制--shmctl

int shmctl(int shmid,int cmd,struct shmid_ds *buf);

成功时返回0,失败时返回EOF

shmid 要操作的共享内存的id

cmd 要执行的操作 IPC_STAT IPC_SET IPC _RMID(删除共享内存)

buf 保存或设置共享内存属性的地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值