同步mmaped区域访问的正确方法是什么

时间:2016-10-06 10:54:01

标签: synchronization mmap

我需要在不同的进程之间交换一些变量,并通过共享内存来尝试。以下代码是此尝试的简化版本。该程序按预期工作,但我想确保交换不仅因为运气而有效。

我的主要问题是,将所有指针声明为volatile是否足够,以确保编译器无法优化内存读取?或者我是否需要插入一些额外的同步命令?

#include <sys/mman.h>
#include <iostream>
#include <unistd.h>
#include <fcntl.h>
#include <type_traits>

struct Exchange
{
    int x;
};

int main()
{
    int fd = open("/dev/shm/foobar", O_RDWR | O_CREAT, 0600);
    if(fd == -1)
    {
        std::cerr << "Open failed\n";
        return 1;
    }
    if(ftruncate(fd, sizeof(Exchange)))
    {
        close(fd);
        std::cerr << "Resize failed\n";
        return 1;
    }
    auto xch = static_cast<volatile Exchange*>(
                    mmap(0, sizeof(Exchange),
                         PROT_READ | PROT_WRITE, MAP_SHARED,
                         fd, 0));
    if(!xch)
    {
        std::cerr << "no mapping\n";
        return 1;
    }
    xch->x=23;
    while(1)
    {
        // Do I need to insert some sync instruction here?
        std::cout << xch->x << std::endl;
        xch->x++;
        msync((void*)(xch), sizeof(*xch), MS_SYNC);
        sleep(1);
    }
}

1 个答案:

答案 0 :(得分:1)

由于您已将msyncMS_SYNC结合使用,因此不再需要进一步同步。

必备的手册页部分:

  

msync()刷新对文件的内核副本所做的更改          使用mmap(2)映射到内存中回到文件系统。

  

MS_SYNC:                 请求更新并等待它完成。

对于阅读,也不需要再进行同步。使用msync将数据写回文件,该文件将文件的页面标记为“脏”,并在下次读取时,mmap机制再次读取文件的页面(使用更新的值)。

更多信息: