当一个库被杀死时自动删除它创建的文件
Automatically delete files created by a library when it is killed
我有一个必须创建临时文件的 Linux 动态库。这些文件必须有一个文件名——它们不能被创建并立即取消链接。我也无法拦截像 SIGINT 和 SIGKILL 这样的信号,因为这是一个被其他程序使用的库。
当创建文件的进程被杀死时,是否有一种理智的方法可以自动删除文件?
澄清:
- 这些确实是我的限制。当我刚刚在问题中说我不能 unlink() 时,请不要回答说"你可以 unlink()"。
- 我意识到这将需要操作系统支持——显然,当我的程序被杀死时,它本身就不能运行任何代码来删除文件。但是可能有一些方法可以标记文件,以便操作系统删除它们。
例如,Windows 有一个"关闭时删除"选项,这意味着当您的程序被杀死时,它所拥有的任何打开的文件都会被关闭并自动删除(我认为;我没有尝试过)。如果在某个地方存在这样的功能,那么理论上在 Linux 上这样的事情显然是可能的。我只想知道有没有。
创建一个文件,然后将 /proc/self/fd/X 传递给 LLVM,其中 X 是您的文件描述符。您现在可以取消链接(正如 Basile 建议的那样),
由于 /proc/self 仅在您的程序关闭时才会消失,因此名称和文件的寿命足够长。
虽然这不是特别明智,但 Linux 允许您通过 /proc/$pid/fd/$number 传递已删除文件的名称。
另一个可能的解决方案是 fork() 一个子进程。然后通过某种机制将所有临时文件名发送到此进程。
子进程可以像这样注册以知道其父进程何时被杀死:
#include <sys/prctl.h>
int ret;
ret = prctl (PR_SET_PDEATHSIG, SIGUSR1);
if (ret)
perror ("prctl");
然后它会在父级被杀死时收到SIGUSR1。此时就可以正常删除文件了。
不,在使用您的库的程序没有运行后,您不能删除这些,因为使用它的程序不再运行。
相反,您可能应该
- 在库的正常操作中检查过时/过大/剩余的临时文件(下次运行时清理)
- 创建一个单独的程序来为您管理这些(定期清理)
这感觉像是一个相当普遍的问题(我当然有过),但它源于对您的程序可能发生的事情的误解。 SIGKILL 将在您的程序可以处理的范围之外立即终止它,并且不会运行它的进一步操作。 (一些特殊的可以继续运行)
正如这篇关于这个主题的帖子所说的那样
SIGKILL pulls the rug out from your running process, terminating it immediately.
I have a Linux dynamic library that has to create temporary files.
您可以使用 atexit(3) 注册一个处理程序,该处理程序将在 exit(3) 时间(或 main 的正常终止)删除所有这些临时文件。当然,这不适用于信号。
您可以在一些 tmpfs 文件系统中创建这些文件。然后它们将在关机时被删除。
如果您遵循有关这些文件的一些命名约定,您还可以使用一些清理脚本(由一些 crontab 条目触发)发布您的库。
Is there a sane way to have the files automatically deleted when the process that created them is killed?
一般来说不是(并且不可能有一个具有 POSIX 文件语义的)。您可能会编写一个清理程序(可能使用 inotify(7) 工具)以从外部运行(例如,作为 crontab 作业或某个守护进程)。
您还可以在创建后(使用 open 或 creat)取消链接(2)每个此类临时文件,并为其保留文件描述符。然后,当进程终止时,或者当它 close-s 那个文件描述符时,文件资源被回收。 tmpfile(3) 使用了这个技巧。
顺便说一句,如果你使用 LLVM 作为 JIT 翻译器,你可以考虑使用 libgccjit。它能够在没有任何输入文件的情况下生成代码。
这样的临时文件不能被自动删除,因为其他一些进程可以打开它们(通过它们的名字)——在任意时刻。这就是为什么 Linux 不能"关闭时删除"(相反,据传 Windows 只允许单个进程写入给定文件)。
But there may be some way to mark the files so that the OS deletes them.
不,不在 Linux 或 POSIX 上。该功能应由应用程序代码提供。