Ubuntu 10.04,使用MAP_HUGETLB与MAP_SHARED时出错

时间:2011-07-04 18:37:08

标签: c++ linux mmap

以下是我用于使用hugepages在ubuntu中对文件进行mmaping的代码,但此调用失败并显示错误“invalid argument”。但是,当我通过时 MAP_ANON标志在mmap中没有文件描述符参数,然后它可以工作。我无法理解这背后可能的原因。

其次,我无法理解为什么MAP_PRIVATE允许文件mmaping,此标志本身意味着不会将更改写回文件。这总是可以使用MAP_ANON完成,还是我遗漏了什么?

有人可以帮我这些吗?

int32_t main(int32_t argc, char** argv) {
int32_t map_length = 16*1024*1024; // 16 MB , huge page size is 2 MB
int32_t protection = PROT_READ | PROT_WRITE;
int32_t flags = MAP_SHARED | MAP_HUGETLB;
int32_t file__ = open("test",O_RDWR|O_CREAT | O_LARGEFILE,s_IRWXU | S_IRGRP | S_IROTH);
if(file__ < 0 ) {
    std::cerr << "Unable to open file\n";
    return -1;
}

if (ftruncate(file__, map_length) < 0) {
    std::cerr
    << "main :: unable to truncate the file\n"
    << "main :: " << strerror(errno) << "\n"
    << "main :: error number is " << errno << "\n";
    return -1;
}
void *addr= mmap(NULL, map_length, protection, flags, file__, 0);
if (addr == MAP_FAILED) {
    perror("mmap");
    return -1;
}
const char* msg = "Hello World\n";
int32_t len = strlen(msg);
memcpy(addr,msg,len);
munmap(addr, map_length);
close(file__);
return 0;
}

2 个答案:

答案 0 :(得分:4)

你的问题都归结为同一点:使用mmap()可以获得两种映射:匿名内存和文件。

匿名内存(如手册页中所述)不受文件系统中任何文件的支持。相反,从MAP_ANON调用mmap()返回的内存是纯系统内存。该接口的主要用户是C库,它使用它来获取malloc / free的后备存储。因此,使用MAP_ANON明确表示您不想映射文件。

文件支持的内存将文件(或部分文件)混合到应用程序的地址空间中。在这种情况下,内存内容实际上由文件的内容支持。将MAP_PRIVATE标志视为首先为文件分配内存,然后将内容复制到此内存中。事实上,这不是内核正在做的事情,而是让我们假装。

HUGE_TLB是内核为匿名内存提供的功能(请参阅mmap()手册页中引用的Documentation / vm / hugetlb-page.txt)。这应该是在将HUGETLB用于文件时mmap()调用失败的原因。 *编辑:不完全正确。有一个RAM文件系统(hugetlbfs)支持大页面。但是,huge_tlb映射不适用于任意文件,因为我理解文档。*

有关如何使用HUGE_TLB和相应的内存文件系统(hugetlbfs)的详细信息,您可能需要考虑LWN上的以下文章:

答案 1 :(得分:0)

将MAP_PRIVATE添加到为我修复的标志中。