Linux POSIX IPC 共享内存(2)

MAP_32BIT把映射区的头2GB个字节映射到进程的地址空间,仅限域x86-64平台的64位程序,在早期64位处理器平台上,可以用来提高上下文切换的性能。当设置了MAP_FIXED时此选项自动被忽略

MAP_ANONYMOUS映射不会备份到任何文件,fd和offset参数都被忽略,通常和MAP_SHARED连用

MAP_DENYWRITEignored.

MAP_EXECUTABLEignored

MAP_FILE用来保持兼容性,ignored

MAP_FIXED不要对addr参数进行处理确确实实的放在addr指向的地址,此时addr一定时页大小的整数倍,

MAP_GROWSDOWN用在栈中,告诉VMM映射区应该向低地址扩展

MAP_HUGETLB (since Linux 2.6.32)用于分配"大页"

fd: file decriptor
offset: 文件中的偏移量

void* pv=mmap(NULL,4,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,0,0); if(MAP_FAILED==pv) perror("mmap"),exit(-1); 映射机制小解

mmap()就是建立一个指针,这个指针指向页高速缓存的一页,并假设这个页有我们想要访问的文件内容(此时都在虚拟地址空间),当然,这个页描述符会自动的加入的调用进程的页表中。当我们第一次使用这个指针,去访问这个虚拟地址的页时,发现这个页还没有分配物理页框,没有想要的文件,引起缺页中断,系统会把相应的(fd)文件内容放到高速缓存的物理页框(此时才会有对物理地址空间的读写)

映射过程中使用的文件相当于药引子,因为所有进程都是可以通过VFS访问磁盘文件的,所以这个文件相当于对映射内存的一个标识,有了这个位于磁盘的药引子,很多进程都可以根据它找到同一个物理页框,进而实现内存的共享,并不是说就在磁盘上读写

页高速缓存的内容不会立即写到磁盘中,会等几秒,这种机制可以提高效率并保护磁盘

只要内存够大,页高速缓存的内容就会一直存在内存中,以后再有进程对该缓存页的内容访问的需求,就不需要从磁盘中搜索,直接访问缓存页(把这个页加入到进程的页表)就行

mmap()是系统调用,使用一次的开销比较大,但比文件读写的read()/write()进行内核空间到用户空间的数据复制要快,通常只有需要分配的内存>128KB(malloc一次分配33page就是128KB)的时��才会使用mmap()

/shm是一个特殊的文件系统,它不对应磁盘中的区域,而是内存中,所以使用mmap()在这个文件系统中创

/proc 不占用任何磁盘空间

linux采用的是页式管理机制。对于用mmap()映射普通文件来说,进程会在自己的地址空间新增一块空间,空间大小由mmap()的len参数指定,注意,进程并不一定能够对全部新增空间都能进行有效访问。进程能够访问的有效地址大小取决于文件被映射部分的大小。

简单的说,能够容纳文件被映射部分大小的最少页面个数决定了进程从mmap()返回的地址开始,能够有效访问的地址空间大小。超过这个空间大小,内核会根据超过的严重程度返回发送不同的信号给进程。

经过内核!=在内核空间和用户空间来回切换!=在内核空间和用户空间传递复制的数据

页是内存映射的基本单位, 可以理解为实际分配给物理内存的基本单位, 但不是数据操作的基本单位;

页机制是操作系统和CPU约定好的一种方式,OS按照页给CPU按页发虚拟地址,CPU按页解析并处理

操作系统(包括Linux)大量使用的缓存的两个原理:

CPU访问内存的速度远远大于访问磁盘的速度(访问速度差距不是一般的大,差好几个数量级)

数据一旦被访问,就有可能在短期内再次被访问(临时局部原理)

页高速缓存(page cache)是个内存区域,是Linux 内核使用的主要磁盘高速缓存,在绝大多数情况下,内核在读写磁盘时都引用页高速缓存,新页被追加到页高速缓存以满足用户态进程的读请求,如果页不在高速缓存中,新页就被加到高速缓存中,然后就从磁盘读出的数据填充它,如果内存有足够的空闲空间,就让该页在高速缓存中长期保留,使其他进程再使用该页时不再访问磁盘, 即磁盘上的文件缓存到内存后,它的虚拟内存地址可以有多个,但是物理内存地址却只能有一个

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/f70e02fbe6d46da46affd53bd49484e1.html