C ++阻止刷新

时间:2019-01-23 17:51:10

标签: c++ linux flush

我想刷新文件输出流(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完成后,我们立即继续进行比较。 tee的作者中的Btest.out尚未完成。如果是这样,则无法读取该文件(即使存在,正如许多人指出的那样)。

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

1 个答案:

答案 0 :(得分:0)

要恢复系统崩溃,您需要fsync / fdatasync系统调用。

从POSIX:

  

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

对于像问题中所述的简单IPC,您无需执行任何操作。

当A查看B掉落到系统中的信息时,该信息尚未进入磁盘也没关系。 A不会从磁盘上获取它,它将从系统中获取它,并且系统将为您提供最新信息,而不管数据是否已同步到永久存储。