我有一个小例子程序,只是fopen
sa文件,并使用fgets
来读取它。 使用strace
,我注意到第一次调用fgets
运行一个mmap
系统调用,然后读取系统调用用于实际读取文件的内容。 在fclose
,文件被munmap
。 如果我打开直接读/打开/读取文件,这显然不会发生。 我很好奇这个mmap
的目的是什么,它正在完成什么。
在我的基于Linux 2.6.31的系统上,当虚拟内存需求很大的时候,这些mmap
有时会挂几秒钟,在我看来是不必要的。
示例代码:
#include <stdlib.h> #include <stdio.h> int main () { FILE *f; if ( NULL == ( f=fopen( "foo.txt","r" ))) { printf ("Fail to open\n"); } char buf[256]; fgets(buf,256,f); fclose(f); }
上面的代码运行时,这里是相关的strace输出:
open("foo.txt", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=9, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb8039000 read(3, "foo\nbar\n\n"..., 4096) = 9 close(3) = 0 munmap(0xb8039000, 4096) = 0
这不是mmap
编辑的文件 – 在这种情况下, mmap
是匿名使用的(不是在文件上),可能为后续读取将使用的缓冲区分配内存。
实际上malloc
导致了对mmap
这种调用。 同样, munmap
对应一个free
的电话。
mmap
没有映射文件; 而是为stdio FILE
缓冲分配内存。 通常malloc
不会使用mmap
来处理这么小的分配,但似乎glibc的stdio实现直接使用mmap
来获得缓冲区。 这可能是为了确保页面对齐(尽管posix_memalign
可以实现相同的目的)和/或确保关闭文件将缓冲区内存返回给内核。 我质疑页面对齐缓冲区的用处。 大概是为了性能,但是我看不出有什么帮助,除非你读的文件偏移量也是页面对齐的,即使如此,它似乎也是一个可疑的微观优化。
从我读的内存映射函数在处理大文件时很有用。 现在大的定义是我不知道的。 但是对于大文件来说,与“缓冲”I / O调用相比,它们显着更快。
在你发布的例子中,我认为文件是由open()
函数open()
,mmap用于分配内存或其他东西。
从mmap函数的语法可以清楚地看到:
void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);
最后一个参数是文件描述符,它应该是非负的。 而在堆栈跟踪中是-1