mmap系统调用它本身提供了不同于一般对普通文件的访问方式,进程可以像读写内存一样对普通文件的操作。而Posix或系统V的共享内存IPC则纯粹用于共享目的,mmap()实现共享内存也是其主要应用之一。mmap系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以像访问普通内存一样对文件进行访问,不必再调用read(),write()等操作。

我们的程序中大量运用了mmap,用到的正是mmap的这种“像访问普通内存一样对文件进行访问”的功能。实践证明,当要对一个文件频繁的进行访问,并且指针来回移动时,调用mmap比用常规的方法快很多。简单说就是把一个文件的内容在内存里面做一个映像,内存比磁盘快些。基本上它是把一个文件对应到virtual memory 中的一段,并传回一个指针。以后对这段内存做存取时,其实就是对那个档做存取。它就是一种快速文件I/O,而且使用上和存取内存一样方便,只不过会占掉你的 virutal memory。

mmap这个系统调用可以直接对底层的操作,映射硬件地址,实现用户层驱动。

#include <sys/mman.h>

 void*mmap(void *addr, size_t len, int prot, int flag, int filedes, off_t off);
intmunmap(void *addr, size_t len);

该函数各参数的作用图示如下

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfcAAAF1CAYAAAD1DaP0AAAgAElEQVR4AeydB4BVxdXHh6qCFeyKAnbsvSv2RI1ijbEkdv3U2GKLJYItaiyxd4019hZ777HFhhVsoIiCoKCCNN83v7P8n7N339vCvvf27e4ZeDvtzJkz/5k7Z9qd2yEXTaiAIZsOHTrUyumXX34JHTt2DGmcxElpRUfiqVOnhs6dO9fig0c8snZ9caKdNm1a6NSpU1GedSJiADIho+QUL9mF0hBGPEbpzDP9j8rWEI80jburC4Fibam6pHRpHAFHoK0jUFdLlqnEdHoo5VRRKysUXRqOHwXHD+Uvv2zSpfT4FZe1FSd6bGjkVzy28iSen8KwU76kVRg26WQrHX7llYYZYfxDGoXLfffdd4fhw4eHSZMmWbkZcICbm+pFQO2Cuqa+5ptvvrDTTjuFWWedtXqFdskcAUegzSPQISqWiszcNSvNIkr2/FDiGIkjxReidL/kamb4xKdKGX8xAx/xKJZGNPXGhzjQiP/Eq1B+4kOc3LLTsGxaaDBSDKusskpYbrnlwiyzzJIfGIgmm9b91YGAlLtWoN56661w/vnnh3XXXTffFqpDUpfCEXAE2hMCZZ+5//DDD+Htt98OX375Zdhll10KKmcpdoBPlagptjiD7tihY/jpp5/C+++/H4YNGxZ++9vfhu7du1s9pUo0rbiUT+pOaSTbN998EwYMGFBnuX/EiBHhjbfeDD3n6mGddZq2oXyVZzG6NFxbAiuvvHK45ppr0mzc3coQOP3008OECRNMarWBVlYEF9cRcATaAAI10+UyFuTnn38Ozz77bDj55JNrzdCV5ZQpU8LZZ58d7rrrLgXlbTrHDtPXFeLivPE575xzwzejR9WiyXuKOIp1sqwmPPnkk+Giiy4KEydOrJN63Lhx4ZILLgpPPPFEnJJPj442zpRn6hYTlDemUFw2XEvvLMd/9913NgCyxPEPfPxXvRhQT6prbLUjhake3XYEHAFHoJIIlH3mPs8889hSM4qrkKLr2rVrWH/99cOcc85Zp9zWQaLgY8ws3buFJZdeKkyLS/Sd4kw+NdAV4q1w2Wka3D169AjLLrtseOqppwKDjKzp169f6DHv3HaIDyFqlHpU2JHQZIs2+Yq/7JRPoQNW2W0ArVxg80vLkrpTvu6uHgRUR9j8OFuisOqR0iVxBByB9oRA2ZU7YHbr1s0OG40ZMya88sorNjNFoc8+++xh7NixYeGFFw5zzDFHfskeus8++yx89dVXYbXVVgtdunSxfehuM89iHefIkSPD559/brNc+PTs2bNOnTEDhsd7770XVlxxxbD88subEkZ5/vjjj5aeWRYH2KRspZxHjRoVPvjgA1v6n/zzJMufDEbF5XsMe+IvvPBC6NOnT1hmmWUCy/off/yxdejkRXnh9eGHH9o2AoMIwmeeeWbL76OPPjIlvsYaaxgGxjT+QSFoFq8wt1sXAtQh7cmNI+AIOAItiUDtKXCZJKHDY8/8kUceCSi2Cy64IBx66KGBJXsOIO27777htNNOM+WGQvzb3/4WRo8ebXFbbrllOOuss8KQDz8KM3ebJfwwbnx4+NEaPuxP77bbboG9c4w61fHjx4errrrK0n/yySdh6623tkEFiv3TTz8NV1xxRXj11VfDY489Fq6//nqTjRUE0jOLv/HGG00pX3nllbYVwJ74lEmTwx133Rl+t9XW4R/nnhMuu+wyK8/LL78czj33XBt03HrrreHoo482fuecc04gbxT6ddddZ4r+tttuszRzzTVXePTRR8M999xTS24UO4MCfjLI5L/qxUD1pHpTHaotKt5tR8ARcAQqikDslMpuoiLLLbroorl40CgXO79cVKy5NddcM/fuu+9a3kcccUTuqKOOysUOMReVvrmJiHviuThzz8U9cYuL++O5uIyeiwfrzD9kyBDzP/fcc7XKMHny5NzQoUMtLCrY3EorrZS78MILc3FrILfHHnvkohLO0+OOs/9cHGjk/ve//+U22mijXFxNyMfvuuuuuUGDBpn/66+/zsUT7bk4OMmRB/44uMghFyYOMnKLL764+eNKQe6+++6zMlAu4jbbbLPcKaeckot7+UYfDweaDSYYeMUVByubBfifVofA8ccfn3v88cdbndwusCPgCLQtBCoyc2cWw8yY5WztKbPUziyHOH4skTPDZ7/ynXfeMX9U0Pa+8FZbbWVxUaHaPrn2NNnHZxYMn9TAe/DgwWHgwIE2A4cvs3uW6l988cX8a0qkgRf0rCKwZcAhO3jGajaWxCMfhuV8ltiXWGIJS4Obw4Kc4r/rjjvDfx58ILDUvsgii9hqxLHHHhtWXXXVEAcHlv6QQw4J9957r+W/9957F9znN0L/4wg4Ao6A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I+AIOAIZBLhTHqMb7HAfffTR4fnnnw+ff/45XjPVtjfvyl01U8V2dkSY9acjytRNkVLa1D116tSiJc7ySAnhUSheYcSn+Sg85YGb8GJxKa1o4KkRNPGpW/RpvgrDzoaLZ0qDOw1P8eH91pNOOslG6tk07ncEHIG2jUC2/6C0Cy+8cFhhhRXCQw89lL+attpQcOVebTWSkQeFk44IUTqp4qHhpfFqiIVshZFFOgrFn8bhx6BACynRQkpQ/JAllS+9yUl5kJ5waBVWk2ONHCl/xXfoUHtQoXClw4af0k6blrMo6FJ8lDeRxIleftlpmqWXXjoMHjw4PPvss0TnTSEZ8pHucAQcgTaBQNoXqEA8+1xs88ADD4SvvvpKwbXstG+pFVEhjyv3CgE9o9lIaSp9586dA3ce03DGjx9viovGN2HCBFOqWkJSgyT92LFj6yhS8YUHBno+jjBp0iRlZZ84FL8ff/wxzydPEB2KJ0xpCVPDxpYshWyFIYdoke2HH36wbH7l39HKTVkKDTggJhwcMAwGauxfFT5x5CeljJu8yPf777+3ssAjpfn5559Dz549Q69evQLYp0ayp2HudgQcgbaPAM/+XHPNFX7zm9+E++67L9+nqOT0KepjFVZpu3ZvVencPb8mIfDdd9+FTz/91BoSs2MOdKy99tph9dVXD4888kggfsCAAWGZZZYxvijkd955J7z55pumoPjK0WyzzWanPEeMGBHmmGOOcOedd4b5558/bLvttuHFF18M7733nt3G1L9/f1N6HBj57LPPjAeKlYscNtlkE1N077//fkD5ofRuvvnmsPPOO5t8KPn111/f+LIv9e2331qaeeaZJ19e+H755ZdRlmFhvvkWMDm6du0cdtrp92HIkCG2n7XGGmuELbbYLHTtOrMNZF555ZVAnpRzp512Cv369TMeI0d+ExZccP7w3//+18qw1lprRVl2scHK0KFDTcZZZ53VltBGjRoVtt9+e8MMYcDhf//7n+2dLbbYYmGrrbayQRL4fvzxx+Hll182PszcV1111bz8OBgkuIKvBYl7HIE2hYCecdnZwh1wwAFh3Lhx2WBT7MXS1CEuU4DP3MsEbKnZMhJE2RxyyCHhD3/4Q5hlllnCOuusEw488MBwxhlnhNVWWy2guIhj1otyOu2008KHH34YDjroIFtWPu6448LXX39tXzra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3OHKABtVCh8tlRam8zhAvakeod67O6807Uex56//RnCX/VQCD6uwdrOhUe3FlwU65a/QzEx+6uCf55WfeOIJe0qZNd0zzzzTXjjca6+90rPPPpt4ZZL1+h133NGW+hAsbMDiieY333zTXlb8yle+Ymu3wCO0Hn744XT77bennXfe2Waa11xzjaXdY4897KVGZoq8xHjbbbfZk81sGOPUAq8tgoNNjuyFuPPOO00VzcuQPA/Ni4ybb755euSRRyztSiutlNZff30rtwTsSy+9ZLSxz4Ad5syON910U1uvZpYM/bvuuqu9Agkd4OJJa3hAObbddlt7mZJnoOEb69KHH3640fOTn/wkLbroovac88svv5zmn3/+dM8996QJEybYS5fwTHVw8803p1dffTVxWoHnsqGdDXnwDJpIz53/2iCnevI2ZRI+aJFRuMJkK76aLThs764GT7iGhLVgIq7JHNDIkAarBqEs8cevfXng6wm36krhYU8/B2rxVHGdbtNhqwz0B7gxciuOMPUTCIqnn346HXDAASYwEYQI2y233NIEM4Lp5JNPtvvpwXPDDTfYPec8rczzxnvvvXeaNGlSev75500InnPOOWmNNdawp5R/+MMfmqDeeOONTVAfe+yxJuB4jvnggw+2p5FXX3112/yLwH3yySdNRc3RLF62hC6egB5RPOV8wgknQLbBsu7MRjDCVTaVB9wI8V/84hdp2WWXtSeg99lnn3TRRRfZk848pHPIIYfYoAF8l156qZWDTcinnnpquvHGG41vv//979P++++fGCxsv/32Nhj593//dxPIb7/9tu1eP+mkk2yQwMDkjDPOSPvtt5/hZUDEwAQeQR873dkUx6CHO+J5PnqjjTZKPKlN+RD6GNWPbJWNONwYH+f9Ci+zq8ERLry4y0zM3Mu40uIwfdgakVHJnWZUBtGtESr+vDy+nILzMMIlWzg7wYZmla8T6G0FjdSx74jyetVRJWjxcT6dd9NWBhuPffv3dVJWToVxXI4ZO2bNNddMSy+9dHrllVfSEUccYU8OE3/22WfbjBr+/fGPf7TZObNp8vv85z+fbr311rTFFluk4cOHW/oVVljBhP7ll19uM21muMyQmeFiLrjgApsRCwfnt6+66qp09dVXpz333NMu3WGGjLDUkV4GDAh/DDQhOJdYYgmbcTND1+VdzOY5u02e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" alt="" />

如果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。

系统调用mmap()用于共享内存的两种方式:

1、使用普通文件提供的内存映射:

适用于任何进程之间。此时,需要打开或创建一个文件,然后再调用mmap()

典型调用代码如下:

fd=open(name, flag, mode); if(fd<0) ...

ptr=mmap(NULL, len , PROT_READ|PROT_WRITE,MAP_SHARED , fd , 0);

通过mmap()实现共享内存的通信方式有许多特点和要注意的地方,可以参看UNIX网络编程第二卷。

2、使用特殊文件提供匿名内存映射:

适用于具有亲缘关系的进程之间。由于父子进程特殊的亲缘关系,在父进程中先调用mmap(),然后调用 fork()。那么在调用fork()之后,子进程继承父进程匿名映射后的地址空间,同样也继承mmap()返回的地址,这样,父子进程就可以通过映射区域进行通信了。注意,这里不是一般的继承关系。一般来说,子进程单独维护从父进程继承下来的一些变量。而mmap()返回的地址,却由父子进程共同维护。对于具有亲缘关系的进程实现共享内存最好的方式应该是采用匿名内存映射的方式。此时,不必指定具体的文件,只要设置相应的标志即可。

# include < unistd. h>
# include < stdio. h>
# include < sys/ mman. h>
# include < fcntl. h>
# include < stdlib. h> //定义存放记录的结构体 typedef struct
{
int index; //编号 char text[ 10] ; //内容 } RECORD; # define SIZE ( 50)
# define EDIT_INDEX ( 10) int main( void )
{
RECORD record, * p_mapped_memory_addr;
int i, fd;
FILE * fp; //创建文件并写入测试数据 fp = fopen ( "records.dat" , "w+" ) ;
for ( i = 0; i < SIZE; i+ + )
{
record. index = i;
sprintf ( record. text, "No.%d" , i) ;
fwrite ( & record, sizeof ( record) , 1, fp) ; //因为字节序对齐,在32位机上,sizeof(record)=16,并不是14。 }
fclose ( fp) ;
printf ( "Ok, write %d records to the file: records.dat ./n" ,SIZE) ; //将第一30条记录编号修改为300,并相应地修改其内容。 //采用传统方式 fp = fopen ( "records.dat" , "r+" ) ;
fseek ( fp, EDIT_INDEX * sizeof ( record) , SEEK_SET ) ;
fread ( & record, sizeof ( record) , 1, fp) ; record. index = EDIT_INDEX* 10;
sprintf ( record. text, "No.%d" , record. index) ; fseek ( fp, EDIT_INDEX * sizeof ( record) , SEEK_SET ) ;
fwrite ( & record, sizeof ( record) , 1, fp) ;
fclose ( fp) ;
printf ( "Ok, edit the file of records.dat using traditionalmethod./n" ) ; ///////////////////////////////////////// //同样的修改,这次使用内存映射方式。 //将记录映射到内存中 fd = open ( "records.dat" , O_RDWR) ;
p_mapped_memory_addr = ( RECORD * ) mmap( 0, SIZE * sizeof ( record) ,PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0) ;
//修改数据 p_mapped_memory_addr[ EDIT_INDEX] . index = EDIT_INDEX* 10;
sprintf ( p_mapped_memory_addr[ EDIT_INDEX] . text, "No.%d" ,
p_mapped_memory_addr[ EDIT_INDEX] . index) ; /* Synchronize the region starting at ADDR and extending LEN bytes withthe
file it maps. Filesystem operations on a file being mapped are
unpredictable before this is done. Flags are from the MS_* set. This function is a cancellation point and therefore not marked with
__THROW. extern int msync (void *__addr, size_t __len, int __flags);
*/
//将修改写回映射文件中(采用异步写方式) msync( ( void * ) p_mapped_memory_addr, SIZE * sizeof ( record) ,MS_ASYNC) ;
/* Deallocate any mapping for the region starting at ADDR and extendingLEN
bytes. Returns 0 if successful, -1 for errors (and sets errno).
extern int munmap (void *__addr, size_t __len) __THROW;
*/
//释放内存段 munmap( ( void * ) p_mapped_memory_addr, SIZE * sizeof ( record) ) ;
printf ( "Ok, edit the file of records.dat using mmapmethod./n" ) ; //关闭文件 close ( fd) ; return 0; }

Linux系统编程(5)——文件与IO之mmap函数的更多相关文章

  1. linux系统编程之文件与io(一)

    经过了漫长的学习,C语言相关的的基础知识算是告一段落了,这也是尝试用写博客的形式来学习c语言,回过头来看,虽说可能写的内容有些比较简单,但是个人感觉是有史起来学习最踏实的一次,因为里面的每个实验都是自 ...

  2. linux系统编程之文件与io(五)

    上一节中已经学习了文件描述符的复制,复制方法有三种,其中最后一种fcntl还并未使用到,关于这个函数,不光只有复制文件描述符的功能,还有其它一些用法,本节就对其进行一一剖析: fcntl常用操作: 这 ...

  3. linux系统编程之文件与io(四)

    今天继续学习文件与io,主要是学习文件共享及文件.复制文件描述符,有点抽象,主要是概念上的理解,但是很重要,下面一一来分解: 文件共享: 回顾一下,在linux系统调用中,是通过文件描述符来访问文件的 ...

  4. linux系统编程之文件与io(二)

    今天继续学习文件与io,话不多说,开始进入正题: 文件的read和write系统调用: 说明:函数中出现在size_t和ssize_t是针对系统定制的数据类型:     下面以一个实现文件简单拷贝的示 ...

  5. linux系统编程之文件与IO(一):文件描述符、open,close

    什么是IO? 输入/输出是主存和外部设备之间拷贝数据的过程 设备->内存(输入操作) 内存->设备(输出操作) 高级I/O ANSI C提供的标准I/O库称为高级I/O,通常也称为带缓冲的 ...

  6. linux系统编程之文件与IO(七):时间函数小结

    从系统时钟获取时间方式 time函数介绍: 1.函数名称: localtime 2.函数名称: asctime 3.函数名称: ctime 4.函数名称: difftime 5.函数名称: gmtim ...

  7. linux系统编程之文件与IO(四):目录访问相关系统调用

    1. 目录操作相关的系统调用     1.1 mkdir和rmdir系统调用     1.1.1 实例     1.2 chdir, getcwd系统调用     1.2.1 实例     1.3 o ...

  8. linux系统编程之文件与IO(三):利用lseek()创建空洞文件

    一.lseek()系统调用 功能说明: 通过指定相对于开始位置.当前位置或末尾位置的字节数来重定位 curp,这取决于 lseek() 函数中指定的位置 函数原型: #include <sys/ ...

  9. linux系统编程之文件与io(三)

    上次我们利用文件的read和write来实现了简易的cp命令,其中将源文件拷贝到目标文件时,我们给目标文件的权限是写死的,而非根据源文件的权限生成的,如下: 今天就来解决这个问题,来学习获取文件权限相 ...

  10. linux系统编程之文件与IO(八):文件描述符相关操作-dup,dup2,fcntl

    本节目标: 1,文件共享 打开文件内核数据结构 一个进程两次打开同一个文件 两个进程打开同一个文件 2,复制文件描述符(dup.dup2.fcntl) 一,文件共享 1,一个进程打开两个文件内核数据结 ...

随机推荐

  1. haproxy 负载elasticsearch 切换

    Attempted to send a bulk request to Elasticsearch configured at '["http://192.168.32.152:9200&q ...

  2. 2015第15周六Java线程池

    Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具.真正的线程池接口是ExecutorService. 比较重要的几个类: Ex ...

  3. web字体格式及几种在线格式转换工具介绍

    原文地址:http://blog.csdn.net/xiaolongtotop/article/details/8316554 目前,文字信息仍是网站最主要的内容,随着CSS3技术的不断成熟,Web字 ...

  4. ofbiz ins

  5. xcode6和ios 8 百度无法定位解决

    . @interface里: CLLocationManager *locationManager; . 初始化: locationManager = [[CLLocationManager allo ...

  6. UITableView 自定义选中Cell颜色

    cell.selectedBackgroundView = [[UIView alloc] initWithFrame:cell.frame]; cell.selectedBackgroundView ...

  7. proxy 利用get拦截,实现一个生成各种DOM节点的通用函数dom。

    const dom = new Proxy({}, { get(target, property) { return function(attrs = {}, ...children) { const ...

  8. 使用Open Flash Chart(OFC)制作图表(Struts2处理)

    Java开源项目中制作图表比较出色的就是JFreeChart了,相信大家都听说过,它不仅可以做出非常漂亮的柱状图,饼状图,折线图基本图形之外,还能制作甘特图,仪表盘等图表.在Web应用中可以为项目增色 ...

  9. android CMWAP, CMNET有何差别

    什么是CMNET,什么是CMWAP? 答:CMWAP和CMNET仅仅是中国移动为其划分的两个GPRS接入方式.中国移动对CMWAP作了一定的限制,主要表如今CMWAP接入时仅仅能訪问GPRS网络内的I ...

  10. boost 定时器.

    #include <iostream> #include <boost/asio.hpp> int main() { boost::asio::io_service io; b ...