【问题标题】:POSIX name semaphore does not release after process exitsPOSIX 名称信号量在进程退出后不释放
【发布时间】:2016-04-17 19:41:18
【问题描述】:

我正在尝试使用 POSIX 命名信号量进行跨进程同步。我注意到在进程死亡或退出后,信号量仍然被系统打开。

在进程(打开它)死亡或退出后,是否有办法让它关闭/释放?

【问题讨论】:

  • 请向我们展示一个重现您的问题的示例。到目前为止,很难说到底是什么导致了这个问题。
  • sem_overview man page 说:“POSIX 命名信号量具有内核持久性:如果不被 sem_unlink(3) 删除,信号量将一直存在,直到系统关闭”。如果这没有帮助,请澄清您的问题。
  • 我从 POSIX 文档中了解到,当进程崩溃或退出时,默认情况下它不会取消链接信号量。我只是想知道是否有任何选择或解决方法可以做到这一点。
  • @S.X “我只是想知道是否有任何选项或解决方法可以做到这一点。” - 绝对不在 POSIX 中。有些 *nix 系统有扩展来支持这种行为,有些则没有。所有可移植的“解决方案”都围绕着:定期检查(例如来自 cron 的脚本)应用程序是否正在运行,如果没有,则清理 SysV 资源。

标签: c linux posix ipc semaphore


【解决方案1】:

您似乎在进程间通信方面遇到了概念问题。 IPC 机制的生命周期不能直接与任何一个进程的生命周期联系在一起,因为这样它可能会从访问它的其他进程中消失。命名信号量在显式删除之前一直存在是有意的。

The Linux sem_overview(7) manual page虽然不是权威规范,但给出了信号量生命周期管理的破败:

sem_open(3) 函数创建一个新的命名信号量或打开一个现有的命名信号量。打开信号量后,可以使用 sem_post(3) 和 sem_wait(3) 对其进行操作。当进程使用完信号量后,它可以使用 sem_close(3) 关闭信号量。当所有进程都使用完信号量后,可以使用 sem_unlink(3) 将其从系统中删除。

sem_unlink() 的文档清楚表明,您可以在进程仍然打开信号量时取消链接信号量。此后没有进程可以sem_open() 该信号量,最终当打开它的进程数降至零时,它将被清除。这故意类似于常规文件。

如果确实有一个进程应该负责清理给定的命名信号量,那么您应该确保它sem_unlink()s 它。两个相当不错的选择是在您对所有其他需要它的进程都打开它感到满意时立即取消链接,或者注册一个处理取消链接的退出处理程序。如果可行,前者可能会更好。

【讨论】:

  • 感谢您的回复。是否有可能有一个有时间限制的信号量在一段时间后自动清理自己?
  • @SX,POSIX 信号量没有这样的行为,内置的,并且在可以想象这样的事情的范围内,你最接近的是一个 unlinked i> 在固定延迟之后。您可以通过多种方式编写程序来处理它。
  • 我喜欢您的评论,即“IPC 机制的生命周期不能直接与任何一个进程的生命周期联系在一起”。这对我来说很有意义!
  • An IPC mechanism's lifetime cannot be tied directly to the life cycle of any one process:也许并非总是如此,但操作系统可能比它更有帮助。首先,让我们注意到releasecloseunlinkcleanup 都有不同的特定语义。在我看来,如果进程在没有明确执行的情况下退出,那么让操作系统自动release 一个由给定进程获取的信号量将非常有帮助。类似地,如果可以将信号量仅限定为父进程和子进程,操作系统可以自动cleanup
  • @RogerDahl,可以将 POSIX 信号量限定为仅父和子。有人为此目的使用 unnamed 信号量,但 OP 已明确选择了一个已命名的信号量。至于自动发布,当然,这将是有用的——直到它不是。但是,如果您愿意,您可以选择 System V 信号量。
【解决方案2】:

这里有更早的讨论:How do I recover a semaphore when the process that decremented it to zero crashes?。他们在那里讨论了几种可能的解决方案。

简而言之:

  • 没有。如果拥有进程崩溃或被信号杀死,则不会释放 POSIX 信号量。等待过程将不得不永远等待。只要你坚持使用信号量,你就无法解决这个问题。
  • 可以使用套接字或文件锁来实现进程间同步,在进程退出时自动释放。我在上面发布的问题所有者最终选择了文件锁。见his answer。在评论区,他发布了一个讨论此问题的博客链接。

其他可能有帮助的链接:

【讨论】:

    猜你喜欢
    • 2011-07-11
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-23
    相关资源
    最近更新 更多