我在我的程序中有一个无限循环,它将写入一个定义为stdout的文件,直到我杀死它。因此,该文件将永远不会被关闭,并且不会包含写入的内容。杀死命令后关闭文件
有没有办法在kill命令后关闭文件?
我可以用信号,像
signal(SIGTERM, close(filename));
,但我会如何处理所有的终止信号?
我在我的程序中有一个无限循环,它将写入一个定义为stdout的文件,直到我杀死它。因此,该文件将永远不会被关闭,并且不会包含写入的内容。杀死命令后关闭文件
有没有办法在kill命令后关闭文件?
我可以用信号,像
signal(SIGTERM, close(filename));
,但我会如何处理所有的终止信号?
你的问题标记为“LINUX”,所以除非你缓冲自己写,不要刷新缓冲区(例如,使用fwrite
需要有时称之为fflush
时),内容将被写入该文件,因为它会在退出时正确关闭(即使出口受到信号强制)。你不需要fsync
,除非你正在做一些必须在机器崩溃后生存下来的东西(然后你需要知道你在做什么才能使崩溃语义正确)。
既然你提到close
你想在信号处理程序中做什么,它似乎并没有缓冲你的写入,所以你不需要做任何事情。成功调用write
后写入的数据将在文件中结束,除非您的计算机崩溃(或者在冲洗缓冲区缓存之前您的磁盘/文件系统中断,请不必担心)。实际上,当你的程序返回write
时,数据可以被认为写入到文件中,并且可以被读取该文件的其他进程看到(这是一个例外,如果机器崩溃或者几个文件系统边缘情况,但这是一个更复杂的话题)。
如果你在你的信号处理程序中所做的只是close
你的文件描述符和_exit
那么你不需要信号处理程序。
我忘了提及该文件应该取代stdout。我编辑了我的问题。 – systemasis
@systemasis不会改变任何东西。从内核的角度来看,stdout只是一个数字,就像任何其他文件描述符一样。如果你正在用'fwrite' /'printf' /'fprintf'或其他任何东西写缓冲区,你有时需要调用'fflush',但这与关闭文件描述符无关。 – Art
刚刚在循环开始处添加了一个'fflush(stdout)',它完成了这个任务。谢谢。 对不起,@unwind,你说得对,我只是没有把fflush放在正确的地方。 – systemasis
您可以强制刷新你对一些预定义的intervals.You回路中的数据可以使用
int fsync(int fd);
或
int fdatasync(int fd);
FSYNC从内核缓冲区文件刷新到磁盘。除了元数据外,fdatasync也会这样做。
这不保证所有数据在执行kill时都会被刷新。 –
'fsync' /'fdatasync'在这里没有关系。如果您希望机器崩溃的安全性,则“fsync”与使用有关,但它与进程写入文件的数据无关。 – Art
尝试在写入('fflush(my_file);')后在循环中添加刷新。 – unwind
不要使用'signal',使用'sigaction',并为*每个*可能的信号(从0到NSIG-1)设置一个动作。请注意,某些信号不能被捕获为'SIGKILL';所以当需要存储关键数据时,您可能会考虑刷新缓冲区。 –
使用'signal(SIGTERM,close(filename))'不起作用?那是什么功能?并在安装信号处理程序时调用函数将立即“*关闭文件*”,而不是在信号触发时进行。 –