Unix/Linux环境C编程入门教程(27) 内存那些事儿

内存映射机制与系统调用

实际上,内存映射机制并不是完全为了共享内存的目的而设计的,它本身提供了不同于一般普通文件的访问方式,进程可以像访问内存一样对普通文件进程操作.而POSIX或System V共享内存IPC则纯粹是用于共享内存的目的.当然内存映射实现共享内存,也是内存映射的应用之一

内存映射机制的用途: A、以访问内存的方式读写文件; B、实现共享内存;

mmap()系统调用: mmap()系统调用使得进程之间通过映射同一个普通文件而实现共享内存的目的.普通文件被映射到进程的地址空间之后,进程就可以像访问普通内存一样对文件进行访问,不必再调用read()、write()等系统调用操作.

mmap()系统调用介绍: void* mmap(void* addr, size_t len, int prot, int flags, int fd, off_t offset);

该函数在进程的地址空间与文件对象或共享内存对象之间建立一种映射关系;

addr :该参数指定文件应该被映射到进程地址空间的起始地址,一般被指定为一个空指针,此时,程序把选择起始地址的任务留给内核来完成了.这个地址是进程地址空间中需要映射到文件中的内存区域的首地址;也就是说,在进程地址空间中用于文件映射的内存区域的首地址;

len :文件被映射到调用进程的地址空间中的字节数,它从被映射文件开头offset个字节处开始算起,取len个字节,把文件中的这len个字节的文件空间映射到进程的地址空间中;

port :指定文件被映射到内存中之后的访问权限.可取的值有:PORT_READ(可读)、PORT_WRITE(可写)、PORT_EXEC(可执行)、PORT_NONE(不可访问); flags :映射标记;取值如下:MAP_SHARED、MAP_PRIVATE、MAP_FIXED,其中,MAP_SHARED和MAP_PRIVATE必选其一,而MAP_FIXED则不推荐使用;

fd :即将被映射到进程地址空间中的文件的描述符.一般由系统调用open()返回;同时,fd可以指定为-1,此时,必须指定flags参数中的MAP_ANON,表明进程的是匿名映射(不涉及具体的文件名,避免了文件的创建及打开,很显然,只能用于具有亲属关系的进程之间的通信).

offset:从文件开头计算offset个字节处开始映射;也就是,文件中需要被映射的文件内容的起始地址,这个起始地址的计算是以文件开头为参照的;这个参数一般取值为0,表示从文件开头处开始映射; 返回值:文件最终映射到进程地址空间中的起始地址;进程可直接以该地址为有效的起始地址进行操作;也就是文件中开始映射的起始字节点到进程中对应映射内存区的起始地址点处的一个映射;换句话就是说,在进程地址空间中用于文件映射的内存区域的首地址;

系统调用mmap()用于共享内存的两种方式: A、使用普通文件提供的内存映射/共享内存:适用于任何进程之间;此时,需要使用系统调用open()事先打开或创建一个文件,然后再调用mmap(): fd = open(filename, flag, mode); …… ptr = mmap(NULL, len, PORT_READ|PORT_WRITE, MAP_SHARED, fd, 0);五、解除内存映射关系: 当进程间通信结束时,需要解除文件页面空间到进程地址空间之间的映射关系;也就说,进程通信结束时,需要把挂载到进程地址空间上的文件卸载下来;这个任务由系统调用munmap(); int munmap(void* addr, size_t len); 该系统调用用于在进程地址空间中结束映射关系; addr:是调用mmap()返回的进程地址空间中用于文件映射的内存区域的首地址; len :进程地址空间中映射区域的大小,单位:字节; 当映射关系解除之后,对原来映射地址的访问将导致段错误发生; 返回值: -1:失败; 0:成功;内存映射的同步: 一般来说,进程在映射空间中对共享内容的修改并不会直接写回到磁盘文件中,可以通过调用msync()来实现磁盘上文件内容与共享内存区中的内容与一致

你的脸是为了呈现上帝赐给人类最贵重的礼物–微笑,

Unix/Linux环境C编程入门教程(27)  内存那些事儿

相关文章:

你感兴趣的文章:

标签云: