我有一个有两个线程的程序。一个线程(写入线程)写入文件,而另一个线程(读取线程)使用第一个线程的数据。在程序中,文件的同一区域被映射了两次:一次对Writer Thread有读写权限,另一次只对Reader Thread有读权限。 (这两个映射区域与预期的 mmap 具有不同的指针/虚拟地址)。我尝试使用 C++11 原子来控制内存顺序。
这是我的想法:
作者主题:
- 在具有写入权限的内存映射区域中创建数据内容(固定大小)。
- 使用释放内存顺序更新原子变量。
读者主题:
- 使用获取内存顺序不断轮询原子变量,直到有/有新消息。
- 如果有未完成的消息,从只读内存映射区域读取数据。
问题
- 即使只读 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/