有没有办法执行POSIX共享同步对象清理,特别是在进程崩溃时?锁定POSIX信号量解锁是最理想的事情,但自动“收集”队列/共享内存区域也会很好。值得关注的另一件事是我们通常不能使用信号处理程序,因为SIGKILL无法捕获。
我只看到一个替代方案:一些外部守护程序接受订阅,“keep-alive”请求作为监视程序工作,因此没有关于某个对象的通知,它可以根据注册的策略关闭/解锁对象。
有没有更好的选择/主张?我之前从未认真对待POSIX共享对象(套接字足以满足我的所有需求,而且我的意见更有用)并且我没有找到任何适用的文章。我很乐意在这里使用插座,但由于历史原因,我不能这样做。
答案 0 :(得分:3)
您可以使用文件锁定来协调您的流程,而不是使用信号量。文件锁的重要优势在于,如果进程终止,它们将被释放。您可以将每个信号量映射到共享文件中的一个字节的锁定,并知道锁定将在退出时释放;在大多数版本的unix中,你锁定的字节甚至不必存在。在Marc Rochkind的高级Unix编程第1版中有代码,但不知道它是否在最新的第2版中。
答案 1 :(得分:3)
我知道这个问题很老,但另一个很棒的解决方案是POSIX强大的互斥体。当所有者死亡时,它们会自动解锁并进入“不一致标志”状态,并且尝试锁定互斥锁的下一个线程会出现EOWNERDEAD
错误但成功成为互斥锁的新所有者。然后它可以清除互斥锁保护的任何状态(由于前一个所有者的异步终止,它可能处于非常糟糕的不一致状态!)并在解锁之前再次将互斥锁标记为一致。
请参阅有关健壮互斥的文档:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_lock.html
答案 2 :(得分:2)
通常的方法是使用signal handlers。只需捕获信号并调用清理功能。
但你的看门狗守护进程也有一些优点。它肯定会使系统更易于理解和管理。为了使管理变得更简单,应用程序应该在守护程序未运行时启动该守护程序,守护程序应该能够清除上次崩溃中的任何残留。