2016-10-10 42 views
3

我在我的程序中有一个无限循环,它将写入一个定义为stdout的文件,直到我杀死它。因此,该文件将永远不会被关闭,并且不会包含写入的内容。杀死命令后关闭文件

有没有办法在kill命令后关闭文件?

我可以用信号,像

signal(SIGTERM, close(filename)); 

,但我会如何处理所有的终止信号?

+2

尝试在写入('fflush(my_file);')后在循环中添加刷新。 – unwind

+1

不要使用'signal',使用'sigaction',并为*每个*可能的信号(从0到NSIG-1)设置一个动作。请注意,某些信号不能被捕获为'SIGKILL';所以当需要存储关键数据时,您可能会考虑刷新缓冲区。 –

+1

使用'signal(SIGTERM,close(filename))'不起作用?那是什么功能?并在安装信号处理程序时调用函数将立即“*关闭文件*”,而不是在信号触发时进行。 –

回答

2

你的问题标记为“LINUX”,所以除非你缓冲自己写,不要刷新缓冲区(例如,使用fwrite需要有时称之为fflush时),内容将被写入该文件,因为它会在退出时正确关闭(即使出口受到信号强制)。你不需要fsync,除非你正在做一些必须在机器崩溃后生存下来的东西(然后你需要知道你在做什么才能使崩溃语义正确)。

既然你提到close你想在信号处理程序中做什么,它似乎并没有缓冲你的写入,所以你不需要做任何事情。成功调用write后写入的数据将在文件中结束,除非您的计算机崩溃(或者在冲洗缓冲区缓存之前您的磁盘/文件系统中断,请不必担心)。实际上,当你的程序返回write时,数据可以被认为写入到文件中,并且可以被读取该文件的其他进程看到(这是一个例外,如果机器崩溃或者几个文件系统边缘情况,但这是一个更复杂的话题)。

如果你在你的信号处理程序中所做的只是close你的文件描述符和_exit那么你不需要信号处理程序。

+0

我忘了提及该文件应该取代stdout。我编辑了我的问题。 – systemasis

+1

@systemasis不会改变任何东西。从内核的角度来看,stdout只是一个数字,就像任何其他文件描述符一样。如果你正在用'fwrite' /'printf' /'fprintf'或其他任何东西写缓冲区,你有时需要调用'fflush',但这与关闭文件描述符无关。 – Art

+0

刚刚在循环开始处添加了一个'fflush(stdout)',它完成了这个任务。谢谢。 对不起,@unwind,你说得对,我只是没有把fflush放在正确的地方。 – systemasis

0

您可以强制刷新你对一些预定义的intervals.You回路中的数据可以使用

int fsync(int fd); 

int fdatasync(int fd); 

FSYNC从内核缓冲区文件刷新到磁盘。除了元数据外,fdatasync也会这样做。

+0

这不保证所有数据在执行kill时都会被刷新。 –

+0

'fsync' /'fdatasync'在这里没有关系。如果您希望机器崩溃的安全性,则“fsync”与使用有关,但它与进程写入文件的数据无关。 – Art