代码之家  ›  专栏  ›  技术社区  ›  Joseph Garvin

为什么POSIX mmap不返回volatile void*?

  •  10
  • Joseph Garvin  · 技术社区  · 14 年前

    volatile void*

    我最好的猜测是,如果您有一个进程专门写入共享内存段,那么它不需要通过volatile指针查看共享内存,因为它总是正确理解当前的内容;编译器为防止冗余读取所做的任何优化都无关紧要,因为除了编写和更改其下的值之外,没有其他事情。还是有其他历史原因?我倾向于说回来 挥发性空隙* 这将是一个更安全的默认值,那些想要这种优化的人可以手动强制转换为void*。

    POSIX mmap说明: http://opengroup.org/onlinepubs/007908775/xsh/mmap.html

    6 回复  |  直到 14 年前
        1
  •  7
  •   Borealid    14 年前

    贯穿许多软件系统的根深蒂固的假设是,大多数程序员都是顺序程序员。这种情况最近才开始改变。

    mmap 有许多与共享内存无关的用途。如果程序员正在编写多线程程序,他们必须采取自己的步骤来确保安全。使用互斥锁保护每个变量不是默认设置。同样地, mmap公司 假定 另一个线程将对同一个共享内存段进行有争议的访问,或者甚至这样映射的段将被另一个线程访问。

    mmap公司 volatile 会对此产生影响。程序员仍然需要确保安全地访问映射区域,不是吗?

        2
  •  8
  •   caf    14 年前

    实现共享内存只是 mmap() . 实际上,最常见的用法是创建私有映射,包括匿名映射和文件备份映射。这意味着,即使我们接受了你关于要求 volatile -用于共享内存访问的限定指针,这种限定符在一般情况下是多余的。

    记住,你可以永远 添加 指针类型的最终限定符,但不能删除它们。所以,现在 mmap()

    volatile char *foo = mmap();  /* I need volatile */
    

    char *bar = mmap();  /* But _I_ do not */
    

    根据你的建议 常见的 这个案子将不得不抛弃这种不稳定因素。

        3
  •  4
  •   nos    14 年前

    即使它是易失性的,也可以很容易地让两个进程从同一个内存中读取不同的值,所需的只是3。进程在从1读取到内存之间的纳秒内写入。进程和2的读取。进程(除非您可以保证两个进程在几乎完全相同的时钟周期内读取相同的内存。

    需要让所有参与的人合作,并意识到他们如何更新彼此之间的记忆-一些超出mmap范围的东西,一些自愿的东西无法解决。

        4
  •  2
  •   Steven Sudit    14 年前

    我不认为 volatile 做你想做的事。

    基本上,它只是告诉编译器不要通过将变量的值存储在寄存器中来优化变量。这将强制它在每次引用它时检索该值,如果另一个线程(或其他任何线程)可以在此期间更新它,这是一个好主意。

    该函数返回一个void*,但它不会被更新,因此调用它volatile是没有意义的。即使将该值赋给局部volatile void*,也不会得到任何结果。

        5
  •  0
  •   Mark B    14 年前

    这样做可能是出于性能原因,默认情况下不提供任何额外功能。如果您知道在您的特定体系结构上,写入/读取不会被处理器重新排序,那么您可能根本不需要volatile(可能与其他同步结合使用)。编辑:这只是一个例子-可能还有其他各种情况下,你知道你不需要强制重读每次访问内存。

    如果您需要确保每次访问时都从内存中读取所有地址,那么const\ u cast(或C-style cast)volatile将其转换为返回值。

        6
  •  0
  •   terminus    14 年前

    类型 volatile void * void * volatile void *

    char * 或者不管你的数据类型是什么,那么也许这就是指定波动性的正确位置。因此,定义的API很好地承担了在您的脚/volatile下标记内存changable的责任。

    也就是说,从全局来看,我同意你的观点:mmap应该有一个返回类型,声明编译器不应该缓存这个范围。