我正在尝试使用MAP_SHARED创建内存映射文件。当文件大小达到2GB时,我遇到了问题。下面粘贴的代码就是我正在使用的代码(作为测试)。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#define MY_FILE "/dev/shm/mmap_test"
#define BLOCK_SIZE (1024*1024)
#define NUM_FILES 1
void mk_file(int f_num)
{
uint64_t len = 0;
int fd, j, k;
char tmp_file[1024], *x, *rr_addr;
// Open file in /dev/shm
sprintf(tmp_file, "%s%d", MY_FILE, f_num);
fd = open(tmp_file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd == -1)
{
perror("file open");
exit(-1);
}
// 16Gb file
len = 16UL * 1024 * 1024 * 1024;
printf("len: %ld Gb\n", len/(1024*1024*1024));
printf("Mapping %ld blocks\n", len/BLOCK_SIZE);
for (j = 0; j < len/BLOCK_SIZE; j++) {
// Increase the file size
ftruncate(fd, ((j + 1) * BLOCK_SIZE));
// Just mmap memory... don't have file backing
//rr_addr = mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
// MMAP a region to the file at a given offset
rr_addr = mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_NORESERVE, fd, (j * BLOCK_SIZE));
if (rr_addr == MAP_FAILED) {
perror("mmap error");
printf("INDEX: %d\n", j);
exit(-1);
}
// Write to every byte of allocated memory
x = (char *) rr_addr;
for (k = 0; k < BLOCK_SIZE; k++)
{
*x = '1';
x++;
}
}
return;
}
int main(int argc, char **argv)
{
uint64_t i;
for (i = 0; i < NUM_FILES; i++)
mk_file(i);
return 0;
}
在上面的代码中,当文件中的偏移量达到2gb时,我得到一个总线错误。这些是我尝试过的东西:
我想知道这是否是Linux内核中的一个问题?有没有人尝试使用大于2gb的MAP_SHARED mmap'单个文件并成功使用(读/写)?
答案 0 :(得分:2)
我认为问题是j
是int
。当j
达到较大值时,(j + 1) * BLOCK_SIZE
会溢出并且您的ftruncate
调用无法执行您想要的操作。检查ftruncate
的返回值应该确认这一点。
mmap man page专门调用SIGBUS
,意味着文件不支持尝试访问。
答案 1 :(得分:0)
我不确定这对您的情况是否有帮助。当我们遇到大文件问题时,以下内容有所帮助。我们把宏:
#define _FILE_OFFSET_BITS 64
包括标准标题之前。您也可以在调用gcc时在命令行上定义它。