Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.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 写/写是否保证是顺序的?_C_Posix_Libc - Fatal编程技术网

C 写/写是否保证是顺序的?

C 写/写是否保证是顺序的?,c,posix,libc,C,Posix,Libc,通过write(或fwrite)写入的数据是否保证按顺序保存到磁盘?特别是在容错方面。如果系统在写入过程中失败,它的行为是否会像第一个字节先被写入,然后在中途停止写入(与随机写入的块相反) 另外,对write/fwrite的顺序调用是否保证是顺序的?根据POSIX,我只发现调用 Read 保证了以前的写< /代码> .< 我在创建持久化到磁盘的容错数据存储时这样问。我写的逻辑顺序是这样的,错误不会破坏数据,但是如果不遵守逻辑顺序,我就有问题了 注意:我不是问是否保证持久性。只有当我对写入的调用最

通过
write
(或
fwrite
)写入的数据是否保证按顺序保存到磁盘?特别是在容错方面。如果系统在写入过程中失败,它的行为是否会像第一个字节先被写入,然后在中途停止写入(与随机写入的块相反)

另外,对
write
/
fwrite
的顺序调用是否保证是顺序的?根据POSIX,我只发现调用<代码> Read <代码>保证了以前的<代码>写< /代码> .< 我在创建持久化到磁盘的容错数据存储时这样问。我写的逻辑顺序是这样的,错误不会破坏数据,但是如果不遵守逻辑顺序,我就有问题了


注意:我不是问是否保证持久性。只有当我对写入的调用最终持续时,它们才会遵循我实际写入的顺序。

是的,只要我们不是在讨论增加多线程的复杂性。它在磁盘上的顺序将是相同的,因为什么使它成为磁盘。它会缓冲内存,并在内存填满或关闭文件时将内存转储到磁盘。

说明“如果已设置O_DSYNC位,则文件描述符上的写入I/O操作应按照同步I/O数据完整性完成的定义完成”。假设,如果未设置
O_DSYNC
位,则未指定I/O数据完整性完成的同步。POSIX还表示,“POSIX.1-2008的这一卷也没有提到应用程序级缓存的任何影响(如stdio所做的)”,因此我认为不能保证
fwrite()

我不是专家,但我可能知道的足够多,可以为您指出正确的方向:

最糟糕的情况是你失去了权力,所以这是唯一值得考虑的

  • 首先是一个包含X字节有意义内容的文件,以及一个指示该内容的头文件
  • 将Y字节有意义的内容写入不会使X无效的位置
  • 调用
    fsync
    (慢!)
  • 更新标头(可能必须小于磁盘的块大小)
我不知道更改文件长度是否安全。我不知道在多大程度上取决于文件系统装载模式,除了任何“安全”模式都可能完全不可用,因为系统甚至需要一点点性能

请记住,在某些系统上,
fsync
调用存在并且只是返回,而不安全地执行任何操作。你可以知道,因为它很快就会回来。因此,您需要进行相当大的事务(即比应用程序级事务大得多)


请记住,在现实世界中解决这一问题的人至少会得到6位数的高薪。对我们其他人来说,最好的答案要么是“把数据发送给postgres,让它来处理。”要么是“接受我们可能不得不丢失数据并恢复到每小时一次的备份。”

不,一般来说,就POSIX和reality而言,文件系统不提供这种保证。持久化的顺序(磁盘使它们在磁盘上永久化)不是由系统调用的顺序、文件中的位置或磁盘上扇区的顺序决定的。文件系统将要写入内存的数据保留几秒钟,并尽可能多地囤积起来,然后以合适的顺序分批发送到磁盘。不管内核如何将其发送到磁盘,由于NCQ,磁盘本身可以自行重新排序写操作

为了安全起见,文件系统具有确保某种顺序的方法。过去使用了障碍,现在使用了明确的刷新和FUA请求。这有一个好处。但这些是文件系统使用的,而不是应用程序

我强烈建议你读一读关于你的文章。不确定与您有多相关,但它显示了许多开发人员在过去错误地假设的行为


o11c提供的答案是一个很好的方法。

您是否参考了一个标准或帮助页面来说明这一保证?一般来说,磁盘上的持久性和布局顺序都不保证。OP不是问磁盘上的布局,只是问他在读取时会得到的数据顺序。我查看了,但找不到磁盘上的定义“同步I/O数据完整性”,而不是说它是同步写入的。同步写入实际上不是我真正想要的,我只是想要一个有保证的写入顺序(我不在乎它是否真的写入了所有内容)。简而言之,dsync语义与手头的问题无关。您介意定义“失败”吗“更详细<代码>EIO,或者其他什么?@alk任何故障,程序突然中止,断电,冻结。只是防止刷新挂起的磁盘写入磁盘的任何东西。我不认为有任何这样的保证。我正在寻找一种不必依赖
fsync
的解决方案。我不需要同步写入,只需要某种形式的顺序保证(听起来可能不可能)。@edA-qamort-ora-y您可以尝试
manext4
或任何文件系统,查看
data=ordered
auto_da_alloc
等选项。请注意,手册页所称的“默认值”可能不是您在系统上实际使用的值,即使您在
fstab
@edA-qamart-ora-y Fsync中没有任何选项,也不能使写入同步,而是在更新标头之前充当屏障。由于原子扇区写入,头应该正好是512字节。Fsync过去曾被称为“更改的语义”。过去,fsync只从内存缓冲区推送到磁盘。若磁盘也在缓冲写操作,那个么无论如何你们都并没有安全性。新内核正确地将磁盘缓冲区推送到磁盘上。查看
manfsync