2009-11-10 39 views
4

有没有什么方法可以执行POSIX共享同步对象清除,特别是在进程崩溃时?锁定POSIX信号量解锁是最希望的事情,但自动'收集'队列/共享内存区域也会很好。另一个需要注意的地方是我们不能在一般情况下使用信号处理程序,因为SIGKILL不能被捕获。共享POSIX对象在进程结束/死亡时清除

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

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

回答

3

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

+0

你推荐的书非常好。 lockf()至少涵盖了原始问题(信号量死锁)的最危险部分)我构建的原型正常工作。 – 2009-11-13 12:53:48

+0

顺便说一下,lockf()可以与第三个参数设置为0(所有文件)一起使用。这样它不需要任何实际的字节。至少在Linux上。 – 2009-11-13 12:55:11

2

通常的方法是与signal handlers一起使用。只需捕捉信号并调用清理功能即可。

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

+0

问题是,我们应该保持甚至对SIGKILL。我根据你的回答纠正了问题。什么是守护进程我更喜欢系统服务实现,以便能够跟踪依赖关系。 – 2009-11-10 08:51:52

+0

你不应该试图陷入SIGKILL。如果您的代码中存在错误,则无法终止它。所以你不想那样。你想要的是迭代所有资源并检查它们是否仍在使用中。大多数使用SHM的应用程序都提供了清理所有共享资源的工具。我建议将这一步自动化。 – 2009-11-10 10:49:18

+1

不只是“你不应该” - 你不能。 http://linux.die.net/man/2/signal“信号** SIGKILL **和** SIGSTOP **不能被捕获或忽略。” – ephemient 2009-11-10 15:36:10

2

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

看到这里稳健互斥的文档:

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