3Linux内存映射,mmap()函数



1mmap()依赖的头文件

#include <sys/mman.h>

2函数声明:

void *mmap(void *addr, size_t length, intprot, int flags,

    
intfd, off_t offset);

int munmap(void *addr, size_t length);

函数说明:

mmap可以把磁盘文件的一部分直接映射到内存,这样文件中的位置直接就有对应的内存

地址,对文件的读写可以直接用指针来做而不需要read/write函数。

3.内存映射图:


说明:

如果addr参数为NULL,内核会自己在进程地址空间中选择合适的地址建立映射。如果

addr不是NULL,则给内核一个提示,应该从什么地址开始映射,内核会选择addr之上的某个合适的地址开始映射。建立映射后,真正的映射首地址通过返回值可以得到。len参数是需要映射的那一部分文件的长度。off参数是从文件的什么位置开始映射,必须是页大小的整数倍(在32位体系统结构上通常是4K)。filedes是代表该文件的描述符。

prot参数有四种取值:

* PROT_EXEC表示映射的这一段可执行,例如映射共享库

* PROT_READ表示映射的这一段可读

* PROT_WRITE表示映射的这一段可写

* PROT_NONE表示映射的这一段不可访问

flag参数有很多种取值,这里只讲两种,其它取值可查看mmap(2)

* MAP_SHARED多个进程对同一个文件的映射是共享的,一个进程对映射的内存做了修

改,另一个进程也会看到这种变化。

* MAP_PRIVATE多个进程对同一个文件的映射不是共享的,一个进程对映射的内存做了修改,另一个进程并不会看到这种变化,也不会真的写到文件中去。

如果mmap成功则返回映射首地址,如果出错则返回常数MAP_FAILED。当进程终止时,该进程的映射内存会自动解除,也可以调用munmap解除映射。munmap成功返回0,出错返回-1。

下面做一个简单的实验

xingwenpeng@ubuntu:~$ vi hello

xingwenpeng@ubuntu:~$ cat hello

helloworld

xingwenpeng@ubuntu:~$ od -tx1 -tc hello

0000000 68 65 6c 6c 6f 77 6f 72 6c 64 0a

h
 e  l  l o w o
 r  l  d \n

0000013

 

使用mmap映射

#include <stdlib.h>

#include <sys/mman.h>

#include <fcntl.h>

int main(void)

{

int *p;

int fd = open("hello", O_RDWR);

if (fd < 0) {

perror("open hello");

exit(1);

}

p = mmap(NULL, 6, PROT_WRITE, MAP_SHARED, fd, 0);

if (p == MAP_FAILED) {

perror("mmap");

exit(1);

}

close(fd);

p[0] = 0x30313233;

munmap(p, 6);

return 0;

}

案例2

写端案例(注意要传递进去一个已经存在的文件名):

#include<stdio.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<sys/mman.h>

#include<unistd.h>

#include<stdlib.h>

#include<fcntl.h>

 

#define MAPLEN 0x1000

 

void sys_err(char *str,int exitno)

{

   perror(str);

   exit(exitno);

}

 

int main(int argc,char *argv[])

{

   char *mm;

   int fd,i = 0;

   if(argc < 2)

   
{

       printf("./a.out filename\n");

       exit(1);

   
}

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

   if(fd < 0)

   
{

       sys_err("open",1);

   
}

   if(lseek(fd,MAPLEN-1,SEEK_SET) < 0)

   
{

       sys_err("lseek",3);

   
}

   if(write(fd,"\0",1) < 0)

   
{

       sys_err("write",4);

   
}

 

//使用MAP_SHARED共享的方式,也就是说:内存或磁盘文件中的一者发生内容变化

   mm = mmap(NULL,MAPLEN,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);

   if(mm == MAP_FAILED){

       sys_err("mmap",2);

   
}

 

   close(fd);

 

   while(1)

   
{

       sprintf(mm,"hello%d",i++);

       sleep(1);

   
}

 

   munmap(mm,MAPLEN);

   return 0;

}

读端的案例:

#include<stdio.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<sys/mman.h>

#include<unistd.h>

#include<stdlib.h>

#include<fcntl.h>

 

#define MAPLEN 0x1000

void sys_err(char *str,int exitno)

{

   perror(str);

   exit(exitno);

}

 

int main(int argc,char *argv[])

{

   char *mm;

   int fd,i = 0;

   if(argc < 2)

   
{

       printf("./a.out filname\n");

       exit(1);

   
}

   fd = open(argv[1],O_RDWR);

   if(fd < 0)

   
{

       sys_err("open",1);

   
}

   

   mm = mmap(NULL,MAPLEN,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);

   if(mm == MAP_FAILED)

   
{

       sys_err("mmap",2);

   
}

 

   close(fd);

 

   while(1)

   
{

       printf("%s\n",mm);

       sleep(1);

   
}

   
munmap(mm,MAPLEN);

   return 0;

}

 

时间: 2024-10-02 13:53:27

3Linux内存映射,mmap()函数的相关文章

linux mmap 内存映射【转】

转自:http://blog.csdn.net/xyyangkun/article/details/7830313 [-] mmap vs readwritelseek mmap vs malloc mmap共享内存进程通信 总结   http://www.perfgeeks.com/?p=723     mmap() vs read()/write()/lseek() 通过strace统计系统调用的时候,经常可以看到mmap()与mmap2().系统调用mmap()可以将某文件映射至内存(进程

Linux的共享内存及内存映射

一.POSIX共享内存的实现 共享内存是在进程间共享某一块内存.是最快一种ipc通信机构.其中posix共享内存机制 它主要是通过内存映射(mmap)机制来实现的. 在进程间共享内存使用如下固定步骤: 1.创建一个共享内存 int shm_open(const char *name, int oflag, mode_t mode); name是共享内存名字,各个进程通过名字来找到同一块内存. oflag,是这个内存属性.类似于文件属性.使用O_RDWR/O_RDONLY/O_CREAT,第一次创

Linux 内存映射函数 mmap()函数详解

一.概述 内存映射,简而言之就是将用户空间的一段内存区域映射到内核空间,映射成功后,用户对这段内存区域的修改可以直接反映到内核空间,同样,内核空间对这段区域的修改也直接反映用户空间.那么对于内核空间<---->用户空间两者之间需要大量数据传输等操作的话效率是非常高的. 以下是一个把普遍文件映射到用户空间的内存区域的示意图. 图一: 二.基本函数 mmap函数是unix/linux下的系统调用,详细内容可参考<Unix Netword programming>卷二12.2节. mma

mongodb mmap内存映射是把文件中数据全部映射到内存中的吗?

问题描述 mongodb mmap内存映射是把文件中数据全部映射到内存中的吗? 资料上说:在Mongodb中,其使用了操作系统底层提供的内存映射机制,即MMAP.MMAP可以把磁盘文件的一部分或全部内容直接映射到内存,这样文件中的信息位置就会在内存中有对应的地址空间,这时对文件的读写可以直接用指针来做,而不需要read/write函数了.同时操作系统会将数据刷新保存到磁盘上. 我有个疑问:这个内存映射,是把文件中数据全部映射到内存中的吗?还是只是映射一部分内容,那么这部门内容又是什么的呢? 请专

linux网络编程之POSIX共享内存和系列函数

在前面介绍了system v 共享内存的相关知识,现在来稍微看看posix 共享内存 和系列函数. 共享内存简单来说 就是一块真正的物理内存区域,可以使用一些函数将这块区域映射到进程的地址空间进行读写,而posix 共享内存与system v 共享内存不同的是它是用虚拟文件系统(tmpfs)实现的,已经挂载在/dev/shm 下面.man 7 shm_overview 下面 来看系列函数,编译时候加上 -lrt 选项,即连接librt 库 (实时库) 功能:用来创建或打开一个共享内存对象 原型

LDD3学习笔记(18):内存映射和DMA

  1.介绍性材料 #include <linux/mm.h> #include <asm/page.h> 和内存管理相关的大部分函数和结构, 原型和定义在这些头文件. void *__va(unsigned long physaddr); unsigned long __pa(void *kaddr); 在内核逻辑地址和物理地址之间转换的宏定义. PAGE_SIZE PAGE_SHIFT  常量, 给出底层硬件的页的大小(字节)和一个页面号必须被移位来转变为一个物理地址的位 数.

java 深入理解内存映射文件原理_Android

内存映射文件原理 首先说说这篇文章要解决什么问题? 1.虚拟内存与内存映射文件的区别与联系. 2.内存映射文件的原理. 3.内存映射文件的效率. 4.传统IO和内存映射效率对比. 虚拟内存与内存映射文件的区别与联系 二者的联系 虚拟内存和内存映射文件都是将一部分内容加载到,另一部分放在磁盘上的一种机制,二者都是应用程序动态性的基础,由于二者的虚拟性,对于用户都是透明的. 虚拟内存其实就是硬盘的一部分,是计算机RAM与硬盘的数据交换区,因为实际的物理内存可能远小于进程的地址空间,这就需要把内存中暂

Linux下C编程-----IO/文件操作/内存映射 实现简单记录存储(3)

利用linux下的文件内存映射可以实现进程共享数据,我们可以把一个文件映射到虚拟内存中使多个进程进行共享, 到这里我们大概能想到他能应用到的领域 是很广泛的  主要涉及到 mmap  munmap   msync 三个函数的应用 下面贴代码  下面一段代码是为文件建立一个简单的记录存储,并且通过内存映射修改文件内容 /************************************************************************* > File Name: mem

c++-求教!通过内存映射,实现生成的数组存储到文件中,显示出来头100个数?

问题描述 求教!通过内存映射,实现生成的数组存储到文件中,显示出来头100个数? 我目前就了解个大概,现在我不明白const DWORD mmf_size = 512*1024;//?这个地方不懂 ,这个原来的代码部分,我拿别人的代码改的,增加了自己的double的动态数组SigNRead,这个怎么弄 我就想实现,通过内存映射 实现写入 读取 double数组 数组有 1列 90000行个double数组成. #include #include #include #include #define