库被杀死时自动删除库创建的文件

Automatically delete files created by a library when it is killed

我有一个 Linux 动态库,它必须创建临时文件。这些文件必须有一个文件名——它们不能被创建并立即取消链接。我也无法拦截像 SIGINTSIGKILL 这样的信号,因为这是一个被其他程序使用的库。

有没有一种明智的方法可以在创建文件的进程被终止时自动删除这些文件?

说明:

  1. 这些确实是我的局限。当我刚刚在问题中说我不能 unlink().
  2. 时,请不要回答说 "you can unlink()"
  3. 我意识到这将需要 OS 支持 - 显然当我的程序被终止时它不能 运行 任何代码 本身 来删除文件.但可能有一些方法可以标记文件,以便 OS 删除它们。

例如 Windows 有一个 "delete on close" 选项,这意味着当你的程序被杀死时,它所有打开的文件都会被关闭并自动删除(我想;我没试过)。如果某处存在这样的功能,那么在 Linux 上理论上显然有可能发生类似的事情。我只想知道是不是。

I have a Linux dynamic library that has to create temporary files.

您可以使用 atexit(3) to register a handler which would delete all these temporary files at 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 作业,或作为某个守护进程)。

你也可以unlink(2) each such temporary file after creation (with open or creat) and keep a file descriptor for it. Then, when the process is terminated, or when it close-s that file descriptor, the file resource are reclaimed. That trick is used by tmpfile(3).

顺便说一句,如果你使用 LLVM 作为 JIT 翻译器,你可以考虑使用 libgccjit。它能够在没有任何输入文件的情况下生成代码。

此类临时文件无法自动删除,因为某些 other 进程可能会在任意时刻打开它们(通过它们的名称)。这就是为什么 Linux 不能有 "delete on close"(相反,传言 Windows 只允许一个进程写入给定文件)。

But there may be some way to mark the files so that the OS deletes them.

不,不在 Linux 或 POSIX 上。该功能应由应用程序代码提供。

不,在使用您的库的程序不是 运行ning 后,您不能删除这些,因为使用它的程序不再是 运行ning。

相反,您可能应该

  • 在你的图书馆的正常运行中检查 outdated/oversize/leftover 个临时文件(由下一个 运行 清除)
  • 创建一个单独的程序来为您管理这些(定期清理)

这感觉像是一个相当普遍的问题(我当然遇到过),但它源于对您的程序可能发生的事情的误解。 SIGKILL 将在您的程序无法处理的情况下立即终止它,并且它不会进行进一步的操作 运行。 (几个特别的可以继续运行ning)

正如this post on the subject所说

SIGKILL pulls the rug out from your running process, terminating it immediately.

虽然这不是特别理智,Linux 也允许您通过 /proc/$pid/fd/$number 传递已删除文件的名称。

创建一个文件,然后将 /proc/self/fd/X 传递给 LLVM,其中 X 是您的文件描述符。您现在可以取消链接(如 Basile 建议的那样),

由于 /proc/self 只有在您的程序关闭时才会消失,因此名称和文件会存在足够长的时间。

另一个可能的解决方案是 fork() child 进程。然后通过某种机制将所有临时文件名发送到此进程。

child 进程可以注册以了解其 parent 何时被终止,如下所示:

#include <sys/prctl.h>
int ret;
ret = prctl (PR_SET_PDEATHSIG, SIGUSR1);
if (ret)
        perror ("prctl");

然后当 parent 被杀死时它会收到 SIGUSR1。到时候就可以正常删除文件了。