jjzjj

linux - 内存 CAS、mmap 和 Posix 读/写的交互

coder 2023-06-22 原文

如果重要的话,所有这些都是指 Linux,内核版本 3.13,以防 Posixen 之间存在不同的行为 - 尽管如果有人知道其他变体的情况,那将会很有趣。

我目前的理解是:

  1. Posix read(2) 和 write(2) 调用相互之间是原子的(这是 Posix 标准强制要求的)。如果我在该位置同时读取()一些字节和写入(),我将看到全部或没有。编辑:查看评论,对于许多文件系统,它只是按页面原子化。

  2. write(2) 调用对于 mmap 是原子的——如果我 write() 到一些字节,同时通过 mmap 读取缓冲区,我将看到所有写入或没有写入(我相信这是并非由 Posix 严格强制要求,而是 Linux 和许多其他操作系统管理页面缓存的方式的产物,并且仅适用于命中一页的写入。

  3. Mmap 写入不保证在任何方面都是原子的 - 其他读者可能会看到部分写入,同一部分中的其他写入者可能会混合。实际上,可能有最小的原子大小,但我不知道这是什么或如何保证它。有没有人对此有任何见解?

  4. 如果我在 mmap 缓冲区中的内存位置上执行 CPU CAS,它会“做我想做的事”,只要实际具有 CAS 语义,任何成功的写入都保证是对其他读取器(无论是通过 mmap 还是 read())原子可见/不可见,只要我保持 CPU 规定的对齐限制即可。

我是否清楚这一点,是否有我可以查看的实现或文档以更深入地了解这些交互?

最佳答案

根据 POSIX 原理:

I/O is intended to be atomic to ordinary files and pipes and FIFOs. (...) The behavior for other device types is also left unspecified, but the wording is intended to imply that future standards might choose to specify atomicity (or not).

因此 POSIX 似乎无法保证特殊文件的原子性,例如 mmaping/dev/zero。

Applications need to know how large a write request can be expected to be performed atomically. This maximum is called {PIPE_BUF}.

即使在常规文件上,如果写入少于 PIPE_BUF 字节,原子写入也仅由 POSIX 保证。

来自 linux 手册页:

However, on Linux before version 3.14, this was not the case: if two processes that share an open file descriptor (see open(2)) perform a write() (or writev(2)) at the same time, then the I/O operations were not atomic with respect updating the file offset, with the result that the blocks of data output by the two processes might (incorrectly) overlap. This problem was fixed in Linux 3.14.

顺便说一句,对于 read() 也是如此。

我找不到任何可以证实 2) 的东西。 POSIX 不需要这样:

The application must ensure correct synchronization when using mmap() in conjunction with any other file access method, such as read() and write(), standard input/output, and shmat().

POSIX 对 3) 如此说是有道理的,因为在写入内存位置时需要知道对象大小。

如果你进行原子比较和交换,那么单个单词将被原子更新,这并不意味着整个写入都是原子的,除非你使用 CAS 操作来构建更复杂的操作,如锁或事务内存。

http://man7.org/linux/man-pages/man2/write.2.html

http://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html

http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html

http://pubs.opengroup.org/onlinepubs/9699919799/functions/mmap.html

关于linux - 内存 CAS、mmap 和 Posix 读/写的交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23896278/

有关linux - 内存 CAS、mmap 和 Posix 读/写的交互的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby-on-rails - 如何在 ruby​​ 交互式 shell 中有多行? - 2

    这可能是个愚蠢的问题。但是,我是一个新手......你怎么能在交互式ruby​​shell中有多行代码?好像你只能有一条长线。按回车键运行代码。无论如何我可以在不运行代码的情况下跳到下一行吗?再次抱歉,如果这是一个愚蠢的问题。谢谢。 最佳答案 这是一个例子:2.1.2:053>a=1=>12.1.2:054>b=2=>22.1.2:055>a+b=>32.1.2:056>ifa>b#Thecode‘if..."startsthedefinitionoftheconditionalstatement.2.1.2:057?>puts"f

  3. ruby-on-rails - Ruby 中的内存模型 - 2

    ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序

  4. 键删除后 ruby​​ 哈希内存泄漏 - 2

    你好,我无法成功如何在散列中删除key后释放内存。当我从哈希中删除键时,内存不会释放,也不会在手动调用GC.start后释放。当从Hash中删除键并且这些对象在某处泄漏时,这是预期的行为还是GC不释放内存?如何在Ruby中删除Hash中的键并在内存中取消分配它?例子:irb(main):001:0>`ps-orss=-p#{Process.pid}`.to_i=>4748irb(main):002:0>a={}=>{}irb(main):003:0>1000000.times{|i|a[i]="test#{i}"}=>1000000irb(main):004:0>`ps-orss=-p

  5. ruby-on-rails - HTTParty 的内存问题和下载大文件 - 2

    这会导致Ruby出现内存问题吗?我知道如果大小超过10KB,Open-URI会写入TempFile。但是HTTParty会在写入TempFile之前尝试将整个PDF保存到内存吗?src=Tempfile.new("file.pdf")src.binmodesrc.writeHTTParty.get("large_file.pdf").parsed_response 最佳答案 您可以使用Net::HTTP。参见thedocumentation(特别是标题为“流媒体响应机构”的部分)。这是文档中的示例:uri=URI('http://e

  6. 【Linux操作系统】——网络配置与SSH远程 - 2

    Linux操作系统——网络配置与SSH远程安装完VMware与系统后,需要进行网络配置。第一个目标为进行SSH连接,可以从本机到VMware进行文件传送,首先需要进行网络配置。1.下载远程软件首先需要先下载安装一款远程软件:FinalShell或者xhell7FinalShellxhell7FinalShell下载:Windows下载http://www.hostbuf.com/downloads/finalshell_install.exemacOS下载http://www.hostbuf.com/downloads/finalshell_install.pkg2.配置CentOS网络安装好

  7. Linux磁盘分区中物理卷(PV)、卷组(VG)、逻辑卷(LV)创建和(LVM)管理 - 2

    文章目录一基础定义二创建逻辑卷2-1准备物理设备2-2创建物理卷2-3创建卷组2-4创建逻辑卷2-5创建文件系统并挂载文件三扩展卷组和缩减卷组3-1准备物理设备3-2创建物理卷3-3扩展卷组3-4查看卷组的详细信息以验证3-5缩减卷组四扩展逻辑卷4-1检查卷组是否有可用的空间4-2扩展逻辑卷4-3扩展文件系统五删除逻辑卷5-1备份数据5-2卸载文件系统5-3删除逻辑卷5-4删除卷组5-5删除物理卷六LVM逻辑卷缩容6-1缩容注意事项6-2标准缩容步骤一基础定义LVM,LogicalVolumeManger,逻辑卷管理,Linux磁盘分区管理的一种机制,建立在硬盘和分区上的一个逻辑层,提高磁盘分

  8. ruby - 如何在 Ruby 中获取 linux 系统信息 - 2

    如何在Ruby中获取linux系统(这必须适用于Fedora、Ubuntu等)的软件/硬件信息? 最佳答案 Chef背后的优秀人才,拥有一颗名为Ohai的优秀gemhttps://github.com/opscode/ohai以散列形式返回系统信息,例如操作系统、内核、规范、fqdn、磁盘、空间、内存、用户、接口(interface)、sshkey等。它非常完整,非常好。它还会安装命令行二进制文件(也称为ohai)。 关于ruby-如何在Ruby中获取linux系统信息,我们在Stack

  9. ruby - rbenv:在 Linux Mint 上找不到 gem 命令 - 2

    我在LinuxMint17.2上。我最近使用apt-getpurgeruby​​删除了ruby​​。然后我安装了rbenv然后rbenvinstall2.3.0所以现在,~/.rbenv/versions/2.3.0/bin/ruby存在。但是现在,我无法执行geminstallrubocop。我明白了:$geminstallrubocoprbenv:gem:commandnotfoundThe`gem'commandexistsintheseRubyversions:2.3.0但是我可以~/.rbenv/versions/2.3.0/bin/geminstallrubocop。但是,

  10. ruby - 在 Linux 上编译 Ruby 1.9.2 所需的先决条件? - 2

    我是Ruby和RoR的新手。我有一个带有Ubuntu镜像的干净Linode实例,我想从源代码编译Ruby而不是使用apt-get。我已经在谷歌上搜索了执行此操作的说明,但经过一些尝试后,当我尝试运行一些教程示例时,我不断收到有关缺少zlib和其他一些包的错误。任何人都可以给我详细的说明(或链接),教我如何在从源代码编译Ruby之前安装必要的必备包吗?我的目的是编译Ruby的最新稳定版本,然后安装Rubygems和Rails。提前感谢您的帮助!!! 最佳答案 Thisblogpost涵盖从源代码编译ruby​​所需的包和安装过程;它引

随机推荐