【发布时间】:2011-11-05 12:50:44
【问题描述】:
我正在尝试使用以下代码 (test.c) “映射”一个二进制文件 (~ 8Gb)。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
int main(int argc, char *argv[])
{
const char *memblock;
int fd;
struct stat sb;
fd = open(argv[1], O_RDONLY);
fstat(fd, &sb);
printf("Size: %lu\n", (uint64_t)sb.st_size);
memblock = mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, fd, 0);
if (memblock == MAP_FAILED) handle_error("mmap");
for(uint64_t i = 0; i < 10; i++)
{
printf("[%lu]=%X ", i, memblock[i]);
}
printf("\n");
return 0;
}
test.c 使用gcc -std=c99 test.c -o test 和file 编译,测试返回:test: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
虽然这对小文件很有效,但当我尝试加载大文件时会出现分段错误。程序实际返回:
Size: 8274324021
mmap: Cannot allocate memory
我设法使用 boost::iostreams::mapped_file 映射整个文件,但我想使用 C 和系统调用来映射。我的代码有什么问题?
【问题讨论】:
-
您需要使用
O_LARGEFILE标志打开文件。检查手册。不确定 >4GB 文件是否可以mmaped。 -
此处无法重现。您的代码在 9G 文件上运行良好。你有多少(RAM + SWAP)?您当前的 /proc/sys/vm/overcommit_memory 政策是什么?
-
@Mat $free -m #Mem{ 总计:1984,使用:1923,免费 60} Swap{ 总计:2021,使用:0,免费:2021} $ cat /proc/sys/vm /overcommit_memory #returns 0
-
@phoxis 32 位机器需要该标志。 Ref
-
@Emer:抱歉,我刚刚注意到
x86_64