CentOS7环境下MAP_HUGE_1GB与MAP_HUGE_2MB未声明问题如何解决?
根因说明
CentOS 7 系统默认搭载的glibc版本为2.17,MAP_HUGE_1GB、MAP_HUGE_2MB属于glibc 2.20版本才正式引入的宏定义,因此即使开启_GNU_SOURCE也无法从系统头文件中找到对应声明。
你遇到的_GNU_SOURCE重定义警告,是因为g链接libstdc时会默认提前定义该宏,手动重复定义就会触发该警告。
解决方案
方案1:手动补充兼容宏定义(推荐,改动最小)
在所有头文件引入的最开头,添加如下代码即可:
// 避免_GNU_SOURCE重复定义 #if !defined(_GNU_SOURCE) #define _GNU_SOURCE #endif // 补充glibc 2.17缺失的大页宏,取值与高版本glibc、内核定义完全兼容 #ifndef MAP_HUGE_2MB #define MAP_HUGE_SHIFT 26 #define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT) #define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT) #endif #include <sys/mman.h>
宏定义逻辑说明:2的21次方等于2MB、2的30次方等于1GB,上述取值完全符合内核大页标记的规范,不会出现兼容性问题。添加完成后即可正常使用MAP_HUGETLB | MAP_HUGE_2MB、MAP_HUGETLB | MAP_HUGE_1GB的组合标志。
方案2:通过hugetlbfs挂载方式使用大页
如果不想修改代码补充宏定义,可以先将hugetlbfs挂载到指定目录,创建对应大小的大页文件后再通过mmap映射,该方式不需要依赖MAP_HUGE_1GB、MAP_HUGE_2MB两个宏。
注意事项
- 2MB大页为CentOS 7内核默认支持,1GB大页需要额外配置内核启动参数:在
grub.cfg的内核启动行添加default_hugepagesz=1G hugepagesz=1G hugepages=预留大页数量,重启系统后生效。 - 若项目使用了预编译头,需要将上述宏定义添加到预编译头的最开头,否则预编译头提前引入头文件会导致宏定义不生效。
内容的提问来源于stack exchange,提问作者HCSF
相关产品推荐
相关产品推荐

