应使用 sysconf(_SC_PAGESIZE),因其是 POSIX 标准函数,返回 long 类型且支持错误检测;而 getpagesize() 非 POSIX、在 macOS 等平台不可靠、无错误返回机制、被 glibc 标记为 legacy。

直接用 sysconf(_SC_PAGESIZE),别碰 getpagesize() —— 后者不是 POSIX 标准,且在某些平台(如 macOS)返回值不可靠。
为什么 getpagesize() 不推荐
这个函数看似简单,但问题不少:
- 它不是 POSIX 标准函数,在 macOS 上实际是 libc 的兼容封装,返回值可能固定为 4096,哪怕系统实际用的是 16KB 大页(如 ARM64 M1/M2 启用 AMP 时)
- Linux 上虽通常可用,但 glibc 文档明确标注其为“legacy”,不保证跨架构一致性(比如在 riscv64 或 s390x 上行为可能不同)
- 没有错误返回机制:
getpagesize()总是返回 int,无法区分“获取失败”和“真就是 4096”
sysconf(_SC_PAGESIZE) 的正确用法
这是 POSIX.1-2001 定义的标准方式,返回值类型为 long,出错时返回 -1 并设置 errno:
#include <unistd.h>
#include <cerrno>
#include <iostream>
long page_size = sysconf(_SC_PAGESIZE);
if (page_size == -1) {
std::cerr << "sysconf(_SC_PAGESIZE) failed: " << strerror(errno) << "\n";
// 降级处理,例如 fallback 到 4096(仅作兜底,不建议长期依赖)
page_size = 4096;
}
注意点:
立即学习“C++免费学习笔记(深入)”;
-
_SC_PAGESIZE是宏,不是字符串,别加引号 - 必须包含
<unistd.h>;C++ 中推荐也加<cerrno>用于错误诊断 - 返回值是
long,别用int接收(尤其在 LP64 环境下,虽然当前所有主流平台该值都 ≤ 65536,但类型安全很重要)
大页(Huge Page)场景下不能只看 _SC_PAGESIZE
sysconf(_SC_PAGESIZE) 返回的是**基础页大小(base page size)**,通常是 4KB。它不反映透明大页(THP)或显式 hugetlbpage 的配置:
- Linux 上启用 THP 后,
mmap()可能自动使用 2MB 页,但sysconf(_SC_PAGESIZE)仍返回 4096 - 若需查询可用的大页尺寸,得读取
/proc/meminfo(如Hugepagesize:行)或调用gethugepagesizes()(glibc 扩展,非 POSIX) - 真正做内存对齐或
mmap(MAP_HUGETLB)时,页大小应由业务逻辑显式指定,而非依赖运行时探测
编译与跨平台兼容性提醒
在 CMake 或 Makefile 中无需额外链接选项 —— sysconf() 属于 libc 基础接口。但要注意:
- Windows MinGW/MSVC 下不支持
sysconf();需用GetSystemInfo()+dwPageSize - 嵌入式平台(如裸机或 uClibc)可能未实现
_SC_PAGESIZE,sysconf()返回 -1 是合法行为 - 如果项目需严格跨平台,建议封装一层:
os_page_size()函数内部按 OS 分支处理,避免上层逻辑散落条件编译
最常被忽略的一点:页大小在进程生命周期内是固定的,但**不是全局常量**—— 它由内核在进程创建时确定,同一内核版本下不同 CPU 架构(x86_64 vs aarch64)或不同内核配置(是否启用 64KB base page)会导致值不同。硬编码 4096 在 ARM64 macOS 或某些定制 Linux 上会出问题。


















