知识点查缺补漏贴01-进程间通讯之mmap文件共享

2019-01-14 10:47:52 浏览数 (1)

引文:

  个人名言:“同一条河里淹死两次的人,是傻子,淹死三次及三次以上的人是超人”。经历过上次悲催的面试,决定沉下心来,好好的补充一下基础知识点。本文是这一系列第一篇:进程间通讯之mmap。

一、概念:什么是mmap?

  通过共享存储实现进程间通讯是一个主要的进程间通讯的方式。它包括磁盘文件的共享和内存的共享,以前总是关注内存的共享,而忽略了磁盘文件的共享,也就是这里要讲的mmap。mmap地址映射是Linux系统提供的一种功能强大的系统调用,最典型的应用是用于显卡内存的映射。同样,对于普通的硬盘文件也可以进行mmap系统调用。mmap()系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以向访问普通内存一样对文件进行访问,不必再调用read(),write()等操作。

注:实际上,mmap()系统调用并不是完全为了用于共享内存而设计的。它本身提供了不同于一般对普通文件的访问方式,进程可以像读写内存一样对普通文件的操作。而Posix或系统V的共享内存IPC则纯粹用于共享目的,当然mmap()实现共享内存也是其主要应用之一。

函数原型如下所示:

       #include <sys/mman.h>

       void * mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset);  //建立映射

       int munmap(void *start, size_t length);  //解除映射

二、参数说明:

  start: 起始虚拟地址,是用户期望使用的虚拟地址,如果进程的虚拟地址空间允许,那么会优先使用该地址。注意:该虚拟地址必须按页尺寸对齐。

      length:映射的长度。

      prot:期望的内存保护,注意不要和打开文件时的属性冲突。属性有PROT_EXEC、PROT_READ、PROT_WRITE、PROT_NONE,分别为可执行、可读、可写、不可访问。

      flags:指明映像对象的类型。类型有:MAP_FIXED(只使用指定的start虚拟地址)、MAP_SHARED(与其他进程共享该映射)、MAP_PRIVATE(创建一个写拷贝的映射,保持数据不影响原有文件)。

      fd: 打开的文件句柄。

      offset: 指明在文件中的偏移,注意:偏移也必须按页尺寸对齐。     

    其中最难理解的是start参数,它填入的是程序员期望使用的虚拟地址。如果该虚拟地址不冲突,那么mmap系统调用返回的值就应该是该虚拟地址。

三、代码实例

本例是打开一个普通的文件,对其进行mmap,然后读取文件内容:

#include <sys/mman.h> /* for mmap and munmap */

#include <sys/types.h> /* for open */

#include <sys/stat.h> /* for open */

#include <fcntl.h>     /* for open */

#include <unistd.h>    /* for lseek and write */

#include <stdio.h>

int main(int argc, char **argv)

{

int fd;

char *mapped_mem, *p;

int flength = 1024;

void * start_addr = 0;

if(argc<2)

{

printf("please input filenamern");

return 0;

}

fd = open(argv[1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);

flength = lseek(fd, 1, SEEK_END);

write(fd, "", 1); /* 在文件最后添加一个空字符,以便下面printf正常工作 */

lseek(fd, 0, SEEK_SET);

mapped_mem = mmap(start_addr, flength, PROT_READ,        //允许读

MAP_PRIVATE,       //不允许其它进程访问此内存区域

fd, 0);

/* 使用映射区域. */

printf("%sn", mapped_mem); /* 为了保证这里工作正常,参数传递的文件名最好是一个文本文件 */

close(fd);

munmap(mapped_mem, flength);

return 0;

}

 四、输出结果:新建文件1.txt 随意输入一些内容即可

[zhangzl@localhost mmap]$ ./ex01 1.txt 2 hello world.

0 人点赞