C++阻塞冲洗

C++ blocking flush

本文关键字:C++      更新时间:2023-10-16

我想刷新一个文件输出流(fstream)。如果我用通常的方式(flush()),程序不会等到文件的内容被实际写入,它会继续。为了说明这个问题,考虑以下场景:

A要求B在文件中写入一些内容。任务完成后,B立即返回。然后,A访问该文件。不幸的是,在操作系统实际写入文件内容之前,B已经完成。该文件尚不存在,A崩溃。

那么,有没有类似于阻塞性冲水的东西?

请注意,当B写入cout,并且B的stdout被重定向到一个文件时,不会出现这个问题。不幸的是,如果B将cout用于其他目的,则无法应用此解决方法。


编辑:我发现问题最终出在其他地方。对于那些感兴趣的人:

简短的版本是,该文件确实存在,但无法读取,因为另一个程序仍在向其写入

长版本:假设我们收到程序A,它可以被认为是某个算法问题的"解决方案"。问题是在线的,这意味着输入必须以小块的形式提供给A。为此,我们创建了一个与a通信的程序B。每当a发送答案时,B就会发送下一个输入块。我们在A和B之间运行一个交互:我们创建一个FIFO文件(mkfifo fifo),然后创建A < fifo | B > fifo

我们想捕获A的输出,看看它是否与某个目标输出文件target.out匹配。一种方法是让B打开一个文件流(fstream fout("test.out", fstream::out)),并在那里写入从a读取的所有内容。另一种解决方案是:A < fifo | tee test.out | B > fifo。在A和B之间的交互完成后,我们运行diff test.out target.out来比较它们。

不幸的是,这两种解决方案都存在以下问题:一旦A完成,我们立即继续进行比较。teeB,无论是test.out的作者,都不需要完成。如果是这样,则无法读取该文件(正如你们中的许多人所指出的那样,即使它存在)。

切换A和B的顺序不考虑在内,因为我们也在捕获A的返回代码。(必须报告解决方案在崩溃时已经崩溃。)

为了防止系统崩溃,您需要fsync/fdasync系统调用。

  • http://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html
  • https://linux.die.net/man/2/fsync

来自POSIX:

fsync()函数应请求打开文件的所有数据由filtes命名的描述符将被传输到存储设备与filtes描述的文件关联。转移是实现定义的。fsync()函数不应返回,直到系统完成该操作或出现错误检测到。

对于问题中描述的简单IPC,您不需要做任何事情。

当A看到B已经推送到系统的信息时,信息还没有进入磁盘并不重要。A不会将数据从磁盘中取出,而是从系统中取出,无论数据是否已同步到永久存储,系统都会为其提供最新信息。

相关文章:
  • 没有找到相关文章