2013-03-01 27 views
0

我正在使用tmpnam()在进程1中生成临时文件名。 打开该文件并将文件名发送到另一进程2. 另一个进程2打开并且写入该文件。内核是否在进程死亡时删除打开的文件

但是,只是我想知道我的进程1是否会死掉,该文件是否会被操作系统删除。看起来不像是这样。在那种情况下,我的选择是什么,以便在进程1死后我没有任何文件。

回答

0

不,内核在您的进程死亡时不会删除打开的文件。

但是,您可以在进程死亡之前删除打开的文件,只要保持打开文件,文件仍然会存在。但是,您将不能再通过名称打开文件- 只能通过打开的文件句柄进行进一步的访问。

例如

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它。

+0

谢谢你的回复! 我正在使用该文件在这两个进程之间传递信息。所以,我不能在创建它之后立即从流程1中取消链接文件,因为流程2不会写入它。 我不能使用tmpfile(),因为那不会给我一个文件名来传递给其他进程。它只是直接给我流。 然后,我使用atexit()函数在退出时取消链接文件。它现在适用于正确的流程退出。但是,对于崩溃,仍然不好。 我想我只需要安装更多的信号处理程序。 – user2125280 2013-03-02 00:54:49

+0

有两种方法可以将打开的fd直接传递给另一个进程。最简单的方法是使用fork/exec:打开的fds不会关闭(除非它们专门设置为这样)。另一种方式是使用unix域套接字和sendmsg;详情请参阅man 3 cmsg。你可以做的另一件事是简单地设置一个cronjob,删除任何不再使用的临时文件。为每个信号设置信号处理程序可能有问题且不可靠。 – 2013-03-04 17:22:12

0

操作系统不会为您删除文件。确定意图会很棘手:是用一些有用的数据写出来的文件,还是现在流程已经消失的文件。

有几种方法可以考虑处理这个问题。在典型情况下,您可以作为退出的一部分进行清理。 如果您遇到问题,您几乎总能得到一个信号,您可以使用它来清理问题。这里有一个例子: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 /中,它可以清理干净,如果它被删除,则以某种方式处理它。

+0

我的文件实际上位于/ tmp /目录中。但是,除非我的流程删除它,否则它将如何清理?我在这里错过了一些东西。对于正确的终止, – user2125280 2013-03-02 01:16:27

+0

atexit()是有用的。但是,考虑到一个进程可能由于各种原因而终止,安装所有信号的处理程序来关闭该进程的打开文件似乎有点不合理。我仍然在看.. – user2125280 2013-03-02 01:20:25