我正在使用tmpnam()在进程1中生成临时文件名。 打开该文件并将文件名发送到另一进程2. 另一个进程2打开并且写入该文件。内核是否在进程死亡时删除打开的文件
但是,只是我想知道我的进程1是否会死掉,该文件是否会被操作系统删除。看起来不像是这样。在那种情况下,我的选择是什么,以便在进程1死后我没有任何文件。
我正在使用tmpnam()在进程1中生成临时文件名。 打开该文件并将文件名发送到另一进程2. 另一个进程2打开并且写入该文件。内核是否在进程死亡时删除打开的文件
但是,只是我想知道我的进程1是否会死掉,该文件是否会被操作系统删除。看起来不像是这样。在那种情况下,我的选择是什么,以便在进程1死后我没有任何文件。
不,内核在您的进程死亡时不会删除打开的文件。
但是,您可以在进程死亡之前删除打开的文件,只要保持打开文件,文件仍然会存在。但是,您将不能再通过名称打开文件- 只能通过打开的文件句柄进行进一步的访问。
例如
fname="/tmp/tempfilename";
fd=open(fname,O_RDWR);
unlink(fname);
/* fd is still a valid handle that can be written to, read from,
lseeked on, or passed to a child process. It will go away
when the process exits.
*/
/* Important note: if you create a temp file like this on a
NFS filesystem, there will be a phantom file named something like
.nfsfile12983719
that will stick around until the file descriptor is closed.
If you delete this file, it will be re-created.
*/
或者,你可以使用tmpfile(3)
其大致做同样的事情,除了 返回FILE *
而非FD它。
操作系统不会为您删除文件。确定意图会很棘手:是用一些有用的数据写出来的文件,还是现在流程已经消失的文件。
有几种方法可以考虑处理这个问题。在典型情况下,您可以作为退出的一部分进行清理。 如果您遇到问题,您几乎总能得到一个信号,您可以使用它来清理问题。这里有一个例子:Basic Signal Handling我拿这个例子。
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
if (signal (SIGINT, termination_handler) == SIG_IGN)
signal (SIGINT, SIG_IGN);
if (signal (SIGHUP, termination_handler) == SIG_IGN)
signal (SIGHUP, SIG_IGN);
if (signal (SIGTERM, termination_handler) == SIG_IGN)
signal (SIGTERM, SIG_IGN);
...
}
另一种方法是在文件名(或文件内容)中嵌入pid。如果你的程序启动并看到一个与你的程序正在运行的实例不匹配的pid文件,你可以尝试清理它。这似乎有点危险。
另外一个稍微有点臭的解决方法是将它放在/ tmp /中,它可以清理干净,如果它被删除,则以某种方式处理它。
我的文件实际上位于/ tmp /目录中。但是,除非我的流程删除它,否则它将如何清理?我在这里错过了一些东西。对于正确的终止, – user2125280 2013-03-02 01:16:27
atexit()是有用的。但是,考虑到一个进程可能由于各种原因而终止,安装所有信号的处理程序来关闭该进程的打开文件似乎有点不合理。我仍然在看.. – user2125280 2013-03-02 01:20:25
谢谢你的回复! 我正在使用该文件在这两个进程之间传递信息。所以,我不能在创建它之后立即从流程1中取消链接文件,因为流程2不会写入它。 我不能使用tmpfile(),因为那不会给我一个文件名来传递给其他进程。它只是直接给我流。 然后,我使用atexit()函数在退出时取消链接文件。它现在适用于正确的流程退出。但是,对于崩溃,仍然不好。 我想我只需要安装更多的信号处理程序。 – user2125280 2013-03-02 00:54:49
有两种方法可以将打开的fd直接传递给另一个进程。最简单的方法是使用fork/exec:打开的fds不会关闭(除非它们专门设置为这样)。另一种方式是使用unix域套接字和sendmsg;详情请参阅man 3 cmsg。你可以做的另一件事是简单地设置一个cronjob,删除任何不再使用的临时文件。为每个信号设置信号处理程序可能有问题且不可靠。 – 2013-03-04 17:22:12