mmap实现共享内存

4 篇文章 0 订阅

可以简单地理解
共享内存:进程A中的一块内存空间和进程B中操作的一块内存空间是同一块内存空间
更详细的原理可以参考,下面主要是如何使用mmap去实现共享内存。

一、mmap参数

在这里插入图片描述
通过man手册可以知道
addr:共享内存的地址,如果为NULL,则会自动分配一块内存
length:共享内存的长度
prot:内存保护的一些flags(比如说:匿名,读,写权限等)
flags:是否对其他进程可见,更新是否会传递到底层文件
fd:文件描述符(用于对内存初始化)
offset:偏移量(用于初始化,offset从fd哪个位置开始读取,length可以表示读取长度)

二、内存不共享情况

利用malloc去创建一块内存
利用fork()去创建一个子进程,子进程将字符写入到共享内存中,主进程将从内存中读数据。(能读到数据就说明,不同进程之间共享了数据)

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>

//创建共享内存
void *shm_mmap_alloc(int size) {
	void *addr = mmap(NULL, size, PROT_READ|PROT_WRITE, 
		MAP_ANON | MAP_SHARED, -1, 0);
	if (addr == MAP_FAILED) {
		return NULL;
	}
	return addr;

}
//释放共享内存
int shm_mmap_free(void *addr, int size) {

	return munmap(addr, size);

}

int main() {
    char* addr=(char*)malloc(1024*1024);
	
	pid_t pid = fork();//创建子进程
	if (pid == 0) {//子进程中写字符
		int i = 0;
		while (i < 26) {
			addr[i] = 'a' + i;
			addr[++i] = '\0';
			sleep(1);
		}		
	} else if (pid > 0) {//父进程中读字符

		int i = 0;
		while (i ++ < 26) {			
			printf("client : %s\n", addr);
			sleep(1);				
		}		
	}

}

可以发现主进程读不到任何数据
在这里插入图片描述

三、内存共享

在其他不变的情况下,通过mmap来创建一块共享内存,munmap去释放一块共享内存。
mmap创建内存代替malloc

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>

//创建共享内存
void *shm_mmap_alloc(int size) {
	void *addr = mmap(NULL, size, PROT_READ|PROT_WRITE, 
		MAP_ANON | MAP_SHARED, -1, 0);
	if (addr == MAP_FAILED) {
		return NULL;
	}
	return addr;

}
//释放共享内存
int shm_mmap_free(void *addr, int size) {

	return munmap(addr, size);

}

int main() {

	char *addr= (char *)shm_mmap_alloc(1024 * 1024);
	pid_t pid = fork();//创建子进程
	if (pid == 0) {//子进程中写字符
		int i = 0;
		while (i < 26) {
			addr[i] = 'a' + i;
			addr[++i] = '\0';
			sleep(1);
		}		
	} else if (pid > 0) {//父进程中读字符

		int i = 0;
		while (i ++ < 26) {			
			printf("client : %s\n", addr);
			sleep(1);				
		}		
	}

	shm_mmap_free(addr, 1024);
}

运行后,可以发现主进程能读出子进程里的数据,因此是内存共享的。
在这里插入图片描述
换种写法

利用从"/dev/zero"中读数据,读到的数据都是空的,都是0,因此可以利用 该文件描述符(fd)用来初始化一块内存。
/dev/zero是什么意思

void *shm_mmap_alloc(int size) {

	int fd = open("/dev/zero", O_RDWR);

	void *addr = mmap(NULL, size, PROT_READ|PROT_WRITE, 
		 MAP_SHARED, fd, 0);
	close(fd);
	
	if (addr == MAP_FAILED) {
		return NULL;
	}
	
	return addr;
}
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菊头蝙蝠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值