前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >知识点查缺补漏贴01-进程间通讯之mmap文件共享

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

作者头像
数据饕餮
发布2019-01-14 10:47:52
3620
发布2019-01-14 10:47:52
举报
文章被收录于专栏:数据饕餮数据饕餮数据饕餮

引文:

  个人名言:“同一条河里淹死两次的人,是傻子,淹死三次及三次以上的人是超人”。经历过上次悲催的面试,决定沉下心来,好好的补充一下基础知识点。本文是这一系列第一篇:进程间通讯之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 filename\r\n");

return 0;

}

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

flength = lseek(fd, 1, SEEK_END);

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

lseek(fd, 0, SEEK_SET);

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

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

fd, 0);

/* 使用映射区域. */

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

close(fd);

munmap(mapped_mem, flength);

return 0;

}

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

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2013年08月23日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档