Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用mmap在文件中写入的原子性?_C_Linux_Filesystems_Mmap - Fatal编程技术网

C 使用mmap在文件中写入的原子性?

C 使用mmap在文件中写入的原子性?,c,linux,filesystems,mmap,C,Linux,Filesystems,Mmap,修改文件内容的一种方法是使用标志MAP\u SHARED运行mmap,然后返回write in memory region。例如: struct data*data; 常量int size=sizeof(结构数据); int fd=打开(“数据文件”,O_RDWR); ftruncate(fd,尺寸); 数据=mmap(空,大小,保护读取,保护写入,映射共享,fd,0); /*访问“数据”成员*/ 让我考虑使用一个日志文件系统( EXT4 > 数据=有序< /代码>或数据=日志< /代码>。断

修改文件内容的一种方法是使用标志
MAP\u SHARED
运行
mmap
,然后返回write in memory region。例如:

struct data*data;
常量int size=sizeof(结构数据);
int fd=打开(“数据文件”,O_RDWR);
ftruncate(fd,尺寸);
数据=mmap(空,大小,保护读取,保护写入,映射共享,fd,0);
/*访问“数据”成员*/

让我考虑使用一个日志文件系统(<代码> EXT4<代码> > <代码>数据=有序< /代码>或<代码>数据=日志< /代码>。断电后,我应该采取哪些预防措施才能从

数据文件
恢复数据

在我看来,Linux保证写操作将被排序,但它不保证任何原子性。因此,应用程序必须实现一种日志,以便恢复
数据\u文件
(与大多数数据库一样)。你确认吗

断电后,我应该采取哪些预防措施才能从
数据文件
恢复数据

由于无法保证
mmap()
'd内存更新的真正原子性,因此需要做两件事:

  • 使用互斥锁或其他同步机制来保护您的数据,并尽可能保持数据处于一致的状态
  • 用于在任何更新后强制将数据写入磁盘
  • 请注意,这很容易受到磁盘上数据的非原子更新的影响,尽管如果您的更新从未跨越页面边界,则这种风险可以最小化。在你的对象的更新过程中,你必须有一个失败,你必须让OS在你的事务中间写这个页面到磁盘。

    如果将互斥体或其他同步对象放在
    mmap()
    'd数据本身中,我怀疑获取互斥体的行为会导致
    mmap()
    'd内存中的更新,从而延迟任何数据写入。在数据本身中放置互斥锁可能会使恢复复杂化,尽管只要您能够确保恢复是单线程的,如果不能完全忽略它,那么这应该不是一个需要解决的问题


    此恢复问题的更好解决方案是,不要使用
    mmap()
    ,而是以确保全部或全无更新的方式显式写入数据,但我怀疑这会对您的设计产生其他重大影响。

    写入操作总是会因硬件/电源故障而中断。因此,它们的原子性只能通过使用在软件中实现的日志或其他方法来保证。但是文件系统可以提供一些原子性,例如(块)写入或任何写入。Linux保证写入操作将按顺序修改
    mmap()
    'd内存不是“写入操作”。@andrewhen我意识到你完全正确。内核甚至无法知道修改的顺序。您认为
    msync
    是原子的吗?可能是
    data=journal
    ,但我认为
    data=ordered
    不是原子的。我认为互斥锁没有帮助。我认为你应该重新阅读Andrew的答案,特别是说“或其他同步机制”的部分。还要听听几乎每个人都告诉你的:确保mmap()的数据操作是原子化的唯一方法是自己强制执行它…@AndrewHenle这就是为什么我从来没有使用mmap()进行编写的原因。;-)这个问题的答案解释了如何确保两个进程能够正确访问mmapped数据->