linux - C++/Linux : Using c++11 atomic to avoid partial read on dual-mapped mmap region

标签 linux multithreading c++11 atomic mmap

我有一个有两个线程的程序。一个线程(写入线程)写入文件,而另一个线程(读取线程)使用第一个线程的数据。在程序中,文件的同一区域被映射了两次:一次对Writer Thread有读写权限,另一次只对Reader Thread有读权限。 (这两个映射区域与预期的 mmap 具有不同的指针/虚拟地址)。我尝试使用 C++11 原子来控制内存顺序。

这是我的想法:

作者主题:

  1. 在具有写入权限的内存映射区域中创建数据内容(固定大小)。
  2. 使用释放内存顺序更新原子变量。

读者主题:

  1. 使用获取内存顺序不断轮询原子变量,直到有/有新消息。
  2. 如果有未完成的消息,从只读内存映射区域读取数据。

问题

  • 即使只读 mmap 区域和可写 mmap 区域引用相同的文件区域,它们也有不同的虚拟内存地址。原子变量可以保护这里的部分读取吗? (即,如果读者线程看到原子变量被获取语义更新,只读内存区域是否只有部分消息或消息根本不可见?)(在我看来,如果两个虚拟内存被映射到相同的物理内存页面,它应该可以工作。)
  • 如果 Reader Thread 使用读取系统调用而不是只读 mmap 区域怎么办?原子内存变量能否避免部分读取?

我已经编写了一个似乎有效的测试程序。但是,我想听取更有经验的程序员/Linux 专家的建议,看看它是否可行。谢谢!

最佳答案

使用不同的虚拟内存范围不会改变这里的事情。为了证明,原子操作在使用相同共享内存的两个进程之间工作得很好。每个人都可以将其映射到不同的虚拟地址。

重要的是它引用了同一 block 物理内存。

read() 系统调用不会锁定内存或以原子方式访问它。它只是在内核中从文件缓存到用户空间完成的一个memcpy()。如果另一个 CPU 正在写入该内存,它可以获得部分读取。

关于linux - C++/Linux : Using c++11 atomic to avoid partial read on dual-mapped mmap region,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33609656/

相关文章:

python - 在 flask 中使用 Gevent : API is not asynchronous

c - 使用管道的 C 多线程聊天程序

c++ - 有没有可能让类型具有在容器中抛出的移动操作?

c++ - 使用自动与显式指定私有(private)结构类型时的行为差异

linux - linux下如何获取字符串的最后一个单词

c++ - gdb fork() 在 Linux 上执行

linux - Git merge 已经分离的目录

c++ - 在 C++ 中修改后修复文件权限?

python - 使用 Tkinter 扫描线程违规

c++ - 使用 RAW 指针对 boost::shared_ptr 变量进行条件初始化