c++ - Ubuntu 10.04,将 MAP_HUGETLB 与 MAP_SHARED 一起使用时出错

标签 c++ linux mmap

以下是我在 ubuntu 中使用大页面映射文件的代码,但此调用失败并出现错误“无效参数”。然而,当我通过 mmap 中没有文件描述符参数的 MAP_ANON 标志,然后它就可以工作了。我无法理解这背后的可能原因。

其次,我无法理解为什么允许使用 MAP_PRIVATE 进行文件映射,而此标志本身意味着不会将任何更改写回文件。这始终可以使用 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;
}

最佳答案

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

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

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

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

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

关于c++ - Ubuntu 10.04,将 MAP_HUGETLB 与 MAP_SHARED 一起使用时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6575010/

相关文章:

c++ - 通过引用传递带有枚举类的枚举

linux - 使用 sed 替换包含引号和单引号的文本

c++ - 可以从用户空间找到 mmap 页面的脏污度吗?

python - 如何从文本文件映射二维数组

c++ - 我需要实现模板功能的特化,该功能执行查找两个C风格字符串中较小的字符串的功能

c++ - 即使定义了搜索路径也无法找到自定义共享库

c++ - 此 vector 实现的可维护性问题

php - 为什么 "500 internal server error"具有 index.php 权限 666?

linux - BASH getopt inside bash 函数

java - 在 jvm 中缓存 tar 以获得更快的文件 I/O?