【问题标题】:Shared POSIX objects cleanup on process end / death进程结束/死亡时的共享 POSIX 对象清理
【发布时间】:2010-12-14 22:48:25
【问题描述】:

有没有办法执行 POSIX 共享同步对象清理,尤其是在进程崩溃时?锁定 POSIX 信号量解除阻塞是最需要的,但自动“收集”队列/共享内存区域也会很好。需要注意的另一件事是我们通常不能使用信号处理程序,因为 SIGKILL 无法被捕获。

我只看到一种选择:一些接受订阅和“保持活动”请求的外部守护程序充当看门狗,因此没有关于某些对象的通知,它可以根据注册策略关闭/解锁对象。

有没有更好的选择/提议?我以前从未认真使用过 POSIX 共享对象(套接字足以满足我的所有需求,而且我认为它更有用)而且我没有找到任何适用的文章。我很乐意在这里使用套接字,但由于历史原因不能。

【问题讨论】:

    标签: c unix synchronization ipc posix


    【解决方案1】:

    通常的方法是使用signal handlers。只需捕获信号并调用清理函数即可。

    但是你的看门狗守护进程也有一些优点。它肯定会使系统更易于理解和管理。为了使管理更简单,您的应用程序应在未运行时启动守护程序,并且该守护程序应能够清除上次崩溃造成的任何残留物。

    【讨论】:

    • 问题是我们应该继续反对 SIGKILL。我根据您的回答更正了问题。与守护进程相关的内容我更喜欢系统服务实现,以便能够跟踪依赖关系。
    • 你不应该尝试捕获 SIGKILL。如果您的代码中存在错误,则无法终止它。所以你不想要那个。您想要的是遍历所有资源并检查它们是否仍在使用中。大多数使用 SHM 的应用程序都提供了清理所有共享资源的工具。我建议自动执行此步骤。
    • 不仅仅是“你不应该”——你不能。 linux.die.net/man/2/signal "信号 SIGKILLSIGSTOP 不能被捕获或忽略。"
    • 抱歉,把它和SIGINT(又名Ctrl-C)和SIGTERMkill 命令)混在一起了。
    • 您也必须在程序启动时释放资源!听起来很疯狂,我知道。原因是在您有机会清理之前,可能会强制您的进程退出系统。在这种情况下,在启动期间分配 SHM 将失败(因为它们仍然存在)。所以你必须做两次:在启动时,首先清理所有东西,然后重新分配。在关机时,只需解除分配。
    【解决方案2】:

    您可以使用文件锁定来协调您的进程,而不是使用信号量。文件锁的一大优点是如果进程终止,它们就会被释放。您可以将每个信号量映射到共享文件中一个字节的锁上,并且知道锁将在退出时释放;在大多数版本的 unix 中,您锁定的字节甚至不必存在。在 Marc Rochkind 的《Advanced Unix Programming 1st edition》一书中有这方面的代码,不过不知道它是否在最新的 2nd edition 中。

    【讨论】:

    • 你推荐的书真的很好。 lockf() 至少涵盖了原始问题中最危险的部分(信号量死锁))我构建的原型工作正常。
    • 顺便说一句,lockf() 可以与第三个参数设置为 0(所有文件)一起使用。这样它就不需要任何真实的字节。至少在 Linux 上。
    【解决方案3】:

    我知道这个问题很老,但另一个很好的解决方案是 POSIX 强大的互斥锁。当所有者死亡时,它们会自动解锁并进入“不一致标志”状态,并且下一个尝试锁定互斥锁的线程会收到EOWNERDEAD 错误,但成功成为互斥锁的新所有者。然后,它能够清除互斥锁所保护的任何状态(由于前一个所有者的异步终止,它可能处于非常糟糕的不一致状态!)并在解锁之前再次将互斥锁标记为一致。

    在此处查看有关健壮互斥锁的文档:

    http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_lock.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多