我想刷新文件输出流(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
的作者中的B
或test.out
尚未完成。如果是这样,则无法读取该文件(即使存在,正如许多人指出的那样)。
不考虑切换A和B的顺序,因为我们也在捕获A的返回码。 (必须报告该解决方案在崩溃时崩溃了。)
答案 0 :(得分:0)
要恢复系统崩溃,您需要fsync / fdatasync系统调用。
从POSIX:
fsync()函数应请求打开文件的所有数据 fildes命名的描述符将被传输到存储设备 与fildes描述的文件关联。的性质 传输是实现定义的。 fsync()函数不得 返回,直到系统完成该操作或出现错误为止 检测到。
对于像问题中所述的简单IPC,您无需执行任何操作。
当A查看B掉落到系统中的信息时,该信息尚未进入磁盘也没关系。 A不会从磁盘上获取它,它将从系统中获取它,并且系统将为您提供最新信息,而不管数据是否已同步到永久存储。