进程间通信(共享内存映射区)

Posted Gwkang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进程间通信(共享内存映射区)相关的知识,希望对你有一定的参考价值。

函数:mmap()

作用:创建内存映射区,将磁盘上的文件数据映射到内存,用户通过内存就能修改磁盘文件。

优点:效率高

缺点:不阻塞,麻烦(对效率不是很高的要求建议用管道)

函数原型:

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

mmap参数说明:

  • addr:内存映射区的首地址,传NULL
  • length:映射区大小,不能为0,一般文件长度多大就指定多大(可通过lseek求)
  • prot:映射区权限(PROT_READ、PROT_WRITE)必须要有读权限
  • flags:设置共享或者私有(MAP_SHARED、MAP_PRIVATE)
  • fd:文件描述符,打开的文件需要读取权限
  • offset:映射文件的偏移量,映射的时候文件指针的偏移量(必须是4k的整数倍)一般填0

返回值:成功返回文件内存映射区的首地址,失败返回MAP_FAILED == (void *)(-1)

 

munmap参数说明:

  • addr:mmap返回的内存映射区的首地址
  • length:映射区大小

返回值:成功返回0, 失败返回-1

 

进程间通信:

  有血缘关系的进程间通信:父子进程共享内存映射区(可创建匿名内存映射区)

  无血缘关系的进程间通信:不能通过匿名内存映射方式通信,只能借助磁盘文件通信

  mmap是不阻塞的。

 

如果创建匿名内存映射区:

  • length需要指定内存映射区大小
  • flags参数需要加 MAP_ANON 宏
  • fd参数要改为-1

常见问题:

  1. 如果对的返回值(ptr)做++操作(ptr++), munmap是否能够成功?
    不能,释放了不改释放的内存
  2. 如果open时O_RDONLY, mmap时pro?参数指定 PROT_READ | PROT_WRITE会怎样?
    mmap调用失败,open是的权限必须大于等于mmap时内存映射区的权限
  3. 如果文件偏移量为1000会怎样?
    调用失败,偏移量必须时4k的整数倍
  4. mmap什么情况下会调用失败?
    问题2、3。还有就是length == 0时
  5. 可以open的时候O_CREAT一个新文件来创建映射区吗?
    可以,但是大小不能为0,需要做文件拓展
  6. 如果通过内存映射区写文件超过内存映射区大小会怎样?
    程序不会出错,但是超过内存映射区的部分不会写入文件

 

以上是关于进程间通信(共享内存映射区)的主要内容,如果未能解决你的问题,请参考以下文章

Linux系统编程 --进程间通信 -共享内存

Linux 进程间通信 共享内存

进程间通信--system V共享内存

进程间通信--system V共享内存

linux进程间通信--共享内存

进程间通信——共享内存