当一个库被杀死时自动删除它创建的文件

Automatically delete files created by a library when it is killed

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

当创建文件的进程被杀死时,是否有一种理智的方法可以自动删除文件?

澄清:

  • 这些确实是我的限制。当我刚刚在问题中说我不能 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 作业或某个守护进程)。

    您还可以在创建后(使用 opencreat)取消链接(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 上。该功能应由应用程序代码提供。


相关推荐

  • Spring部署设置openshift

    Springdeploymentsettingsopenshift我有一个问题让我抓狂了三天。我根据OpenShift帐户上的教程部署了spring-eap6-quickstart代码。我已配置调试选项,并且已将Eclipse工作区与OpehShift服务器同步-服务器上的一切工作正常,但在Eclipse中出现无法消除的错误。我有这个错误:cvc-complex-type.2.4.a:Invali…
    2025-04-161
  • 检查Java中正则表达式中模式的第n次出现

    CheckfornthoccurrenceofpatterninregularexpressioninJava本问题已经有最佳答案,请猛点这里访问。我想使用Java正则表达式检查输入字符串中特定模式的第n次出现。你能建议怎么做吗?这应该可以工作:MatchResultfindNthOccurance(intn,Patternp,CharSequencesrc){Matcherm=p.matcher…
    2025-04-161
  • 如何让 JTable 停留在已编辑的单元格上

    HowtohaveJTablestayingontheeditedcell如果有人编辑JTable的单元格内容并按Enter,则内容会被修改并且表格选择会移动到下一行。是否可以禁止JTable在单元格编辑后转到下一行?原因是我的程序使用ListSelectionListener在单元格选择上同步了其他一些小部件,并且我不想在编辑当前单元格后选择下一行。Enter的默认绑定是名为selectNext…
    2025-04-161
  • Weblogic 12c 部署

    Weblogic12cdeploy我正在尝试将我的应用程序从Tomcat迁移到Weblogic12.2.1.3.0。我能够毫无错误地部署应用程序,但我遇到了与持久性提供程序相关的运行时错误。这是堆栈跟踪:javax.validation.ValidationException:CalltoTraversableResolver.isReachable()threwanexceptionatorg.…
    2025-04-161
  • Resteasy Content-Type 默认值

    ResteasyContent-Typedefaults我正在使用Resteasy编写一个可以返回JSON和XML的应用程序,但可以选择默认为XML。这是我的方法:@GET@Path("/content")@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})publicStringcontentListRequestXm…
    2025-04-161
  • 代码不会停止运行,在 Java 中

    thecodedoesn'tstoprunning,inJava我正在用Java解决项目Euler中的问题10,即"Thesumoftheprimesbelow10is2+3+5+7=17.Findthesumofalltheprimesbelowtwomillion."我的代码是packageprojecteuler_1;importjava.math.BigInteger;importjava…
    2025-04-161
  • Out of memory java heap space

    Outofmemoryjavaheapspace我正在尝试将大量文件从服务器发送到多个客户端。当我尝试发送大小为700mb的文件时,它显示了"OutOfMemoryjavaheapspace"错误。我正在使用Netbeans7.1.2版本。我还在属性中尝试了VMoption。但仍然发生同样的错误。我认为阅读整个文件存在一些问题。下面的代码最多可用于300mb。请给我一些建议。提前致谢publicc…
    2025-04-161
  • Log4j 记录到共享日志文件

    Log4jLoggingtoaSharedLogFile有没有办法将log4j日志记录事件写入也被其他应用程序写入的日志文件。其他应用程序可以是非Java应用程序。有什么缺点?锁定问题?格式化?Log4j有一个SocketAppender,它将向服务发送事件,您可以自己实现或使用与Log4j捆绑的简单实现。它还支持syslogd和Windows事件日志,这对于尝试将日志输出与来自非Java应用程序…
    2025-04-161