【问题标题】:How does posix_memalign differ from mmapposix_memalign 与 mmap 有何不同
【发布时间】:2012-02-26 12:31:02
【问题描述】:

对齐大小为 4096 字节的 posix_memalignmmap 有何不同?它在内部使用mmap 还是其他一些机制?

【问题讨论】:

    标签: c linux x86-64 mmap memory-alignment


    【解决方案1】:

    posix_memalign 是比mmap 更高级别的API,旨在与mallocfreerealloc 互操作。 mmap 的使用更复杂,因为它提供了比posix_memalign 更多的功能(将文件映射到进程的地址空间)。 POSIX 标准未指定其实现方式(以mmap 或其他方式)。

    如果您没有对齐限制,请使用posix_memalign,您可以使用malloc

    【讨论】:

      【解决方案2】:

      对齐大小为 4096 字节的 posix_memalign 与 mmap 有何不同?

      显而易见的答案:posix_memalign 不能通过 fd 映射任意文件。 :)

      关于 posix_memalign 与 mmap(MAP_ANOYMOUS) 的分配行为:我认为不需要 posix_memalign(size) 必须使用 mmap。它还可以与 malloc 共享 sbrk 机制,并返回一个正确对齐的指针,指向部分 brk 区域。

      【讨论】:

        【解决方案3】:

        mmap 可用的地方,posix_memalign 通常使用mmap 实现。主要区别在于posix_memalign 在stdlib.h 中,而mmap 是一个系统调用,它可能不可用并且在不同平台上具有不同的语义。

        【讨论】:

        • mmap 由 POSIX 指定,因此在任何符合标准的平台上应该具有相同的语义。
        • @larsmans: 而mmap 由X/Open (POSIX) 指定MAP_ANON 标志/行为(使用mmap 分配内存)和/或使用-1因为文件描述符不是可移植规范的一部分。请参阅pubs.opengroup.org/onlinepubs/009695399/functions/mmap.html 了解mmap 标准中的(非)内容。
        【解决方案4】:

        从标准 (POSIX) 的角度来看,posix_memalign()mmap() 没有任何联系:

        posix_memalign - 对齐的内存分配

        posix_memalign() 函数应分配 size 字节对齐在 由对齐指定的边界,并应返回指向 在memptr 中分配的内存。

        mmap - 映射内存页

        mmap() 函数应在地址空间之间建立映射 一个进程和一个内存对象。

        以下内存应支持mmap()函数 对象:

        • 常规文件
        • [SHM]> 共享内存对象
        • [TYM] > 类型化内存对象

        未指定对任何其他类型文件的支持。

        特别是,POSIX 没有指定可用于(例如在 Linux 上)使用 mmap() 在没有相应文件的情况下分配内存的 MAP_ANONYMOUS 标志。因此,先验地,这两个函数执行不相关的任务:posix_memalign() 分配动态内存(POSIX mmap() 不能这样做),而 mmap() 将文件映射到进程地址空间(posix_memalign() 不能这样做,如jørgensen’s answer)。

        在谈论支持MAP_ANONYMOUS 的系统时,例如Linux(在问题中已标记),mmap() 获得类似于posix_memalign() 的功能,尽管mmap() 将返回与系统页面对齐的指针大小,而posix_memalign() 也可用于获取具有不同对齐方式的内存。

        最后是memory allocated with posix_memalign() is freed using free(),而mmap() is cleaned up using munmap()

        【讨论】:

        • 如果没有 MAP_ANONYMOUS,您实际上可以打开 /dev/zero 并使用 MAP_PRIVATE 对其进行映射以获得有效的匿名内存。我想我听说在一些较旧的 Unix 上实际上是这样做的,以此来避免在所有事情上都使用 brk。
        • @PeterCordes 我在Wikipedia 上看到过这种技术,但我认为它在任何地方都没有标准化或保证可以工作。至少(根据维基百科页面)它似乎不适用于 Mac OS X/macOS。
        • 在广泛支持 MAP_ANONYMOUS 很久之后出现的现代操作系统实际上并不需要支持 /dev/zero 的 mmap。可移植代码不应该使用它(希望不会),但对于 特定 OS 的 libc 的 malloc 的内部实现当然可以用于大量分配。很少有程序会尝试重新实现 malloc,而且 malloc 库会使用 #ifdef 来选择令人讨厌的回退(需要为其管理 fd),仅在它可以工作且 MAP_ANONYMOUS 不可用的操作系统上。
        猜你喜欢
        • 2014-11-12
        • 1970-01-01
        • 1970-01-01
        • 2020-12-05
        • 1970-01-01
        • 2011-03-23
        • 2023-03-11
        • 2016-03-02
        • 2010-09-07
        相关资源
        最近更新 更多