【发布时间】:2016-09-14 14:20:03
【问题描述】:
我有一个长时间运行的 C 程序,它在开始时打开一个文件,在执行过程中写出“有趣”的东西,并在文件完成之前关闭文件。使用gcc -o test test.c(gcc 版本 5.3.1.)编译的代码如下所示:
//contents of test.c
#include<stdio.h>
FILE * filept;
int main() {
filept = fopen("test.txt","w");
unsigned long i;
for (i = 0; i < 1152921504606846976; ++i) {
if (i == 0) {//This case is interesting!
fprintf(filept, "Hello world\n");
}
}
fclose(filept);
return 0;
}
问题在于,因为这是一个科学计算(想想搜索素数,或者任何你最喜欢的难以破解的东西)它真的可以运行 非常 很久了。由于我确定我没有足够的耐心,我想中止当前的计算,但我想以一种智能的方式通过以某种方式强制程序通过外部手段做到这一点。 em> 清除当前在 OS 缓冲区/磁盘缓存中的所有数据。
这是我尝试过的(对于上面这个伪造的程序,当然不是真正的交易目前仍在运行):
- 按 ctrl+C;或
- 发送
kill -6 <PID>(以及kill -3 <PID>)——正如@BartekBanachewicz 所建议的那样,
但是在这些方法中的任何一种之后,在程序开始时创建的文件test.txt仍然是空的。这意味着,fprintf() 的内容在计算过程中被留在了某个中间缓冲区中,等待一些操作系统/硬件/软件刷新信号,但由于没有获得这样的信号,内容消失了 .这也意味着,@EJP 发表的评论
您的问题是基于一个谬误。 '操作系统中的东西 缓冲区/磁盘缓存'不会丢失。
似乎不适用于这里。经验表明,这些东西确实会丢失。
我使用的是 Ubuntu 16.04,如果可能,并且如果可以安全地以这种方式检索数据,我愿意将调试器附加到此进程。由于我以前从未做过这样的事情,如果有人能给我一个详细的答案,我将不胜感激如何将内容刷新到磁盘中安全可靠。或者我也对其他方法持开放态度。这里没有出错的余地,因为我不会再次重新运行程序。
注意:当然我可以在if 分支内打开和关闭一个文件,但是一旦你有许多 东西要写,那效率就非常低了。无法重新编译程序,因为它仍在进行一些计算。
注 2:最初的问题以与 C++ 相关的稍微抽象的方式被问到同一个问题,并被标记为这样(这就是为什么 cmets 中的人建议 std::flush(),即使这是无济于事一个 C++ 问题)。好吧,我想我当时做了一个重大修改。
有些相关:Will data written via write() be flushed to disk if a process is killed?
【问题讨论】:
-
让程序退出而不是杀死它怎么样?
-
寻找std::flush?
-
@BartekBanachewicz 实际上可能有效......所以我应该向程序发送一个不同的
SIG...信号。我会检查的。 -
杀死程序时是否要强制刷新?
-
您的问题是基于一个谬误。 “操作系统缓冲区/磁盘缓存中的内容”不会丢失。您需要担心的是仍在应用程序中的东西,例如
stdio或streams缓冲区,fflush()和std::flush()是这两个的答案。