欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

Linux - 进程间通信(共享内存 [mmap 实现 + 系统 V]) - mmap 及其相关系统调用

最编程 2024-07-04 07:15:31
...

mmap是linux操作系统提供给用户空间调用的内存映射函数,很多人仅仅只是知道可以通过mmap完成进程间的内存共享和减少用户态到内核态的数据拷贝次数,但是并没有深入理解mmap在操作系统内部是如何实现的,原理是什么
在这里插入图片描述

mmap()系统调用使得进程之间可以通过映射同一个普通文件实现内存共享。普通文件被映射到进程地址空间后,进程可以访问普通内存一样对文件进行访问,不必再调用read和write操作。
注意: mmap并不是完全为了IPC而设计的,只是IPC的一种应用方式,它本身提供了一种像访问普通内存一样的访问对普通文件进行操作的方式。

通过使用带有特殊权限集的虚拟内存段来实现。对这类虚拟内存段的读写会使操作系统去读写磁盘文件中与之对应的部分。 mmap 函数创建一个指向一段内存区域的指针,该内存区域与可以通过一个打开的文件描述符访问的文件的内容相关联
解释如下:

mmap()
#include <sys/mman.h>

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
  • 可以通过传递 offset 参数来改变经共享内存段访问的文件中数据的起始偏移值。
  • 打开的文件描述符由 fd 参数给出。
  • 可以访问的数据量(即内存段的长度)由 length 参数设置。
  • 可以通过 addr 参数来请求使用某个特定的内存地址。如果它的取值是零,结果指针就将自动分配。这是推荐的做法,否则会降低程序的可移植性,因为不同系统上的可用地址范围是不一样的。
  • prot 参数用于设置内存段的访问权限。它是下列常数值的按位或的结果
    • PROT_READ 内存段可读。
    • PROT_WRITE 内存段可写。
    • PROT_EXEC 内存段可执行。
    • PROT_NONE 内存段不能被访问。
  • flags 参数控制程序对该内存段的改变所造成的影响:

在这里插入图片描述
mmap()用于共享内存的量和两种方式如下:

  1. 使用普通文件提供的内存映射,适用于任何进程间,使用该方式需要先打开或者创建一个文件,再调用ngmmap,典型调用代码如下:
fd = open(name.falg.mode);
if(fd < 0)
ptr = mmap(NULL,len.PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
  1. 使用特殊文件提供的内存映射,适用于具有亲缘关系的进程之间,由于父子进程特殊的亲缘关系,在父进程中先调用mmap,调用fork,那么在代用fork之后,子进程可以继承父进程匿名映射后的地址空间,同样也继承mmap返回的地址,这样父子进程就可以通过映射区域进行通信了。(注意:一般来说,子进程单独维护从父进程继承而来的一些变量,而mmap()返回的地址由父子进程共同维护)【具体使用实现敬请期待博主整理】
munmap()

用于解除内存映射,取消参数start所指的映射内存的起始地址,参数length则是欲取消的内存大小,当进程结束或者利用exec相关函数来执行其他程序时,映射内存会自动解除,但关闭对应的文件描述符时不会解除映射。

#include <sys/mman.h>

int munmap(void *addr, size_t length);

推荐阅读