2012-03-19 52 views
3

如果一个进程持有一些自旋锁或信号量并意外退出(例如,被linux杀死),linux会正确释放这些锁吗? 如果linux不做这项工作,为什么?当杀死进程时,linux是否释放了自旋锁/信号量?

+1

如果您对Linux架构感兴趣,因为它涉及同步机制,您可能需要查看futex系统调用的工作方式(“man 7 futex”,“man 2 futex”)。 phtread_mutex和sem_wait都是在阻塞情况下用futex实现的。 – 2012-03-25 04:12:02

回答

8

这取决于你正在谈论的锁的类型。

如果您正在讨论任何类型的内核内部锁,它们将在适当时候发布(因为您的系统很快就会崩溃)。通常,这些类型的锁不是由进程本身所拥有,而是由内部的内核工作流程拥有,并且通常在进程返回到用户空间后不会保持锁定状态。

但是请注意,如果内核是已经死锁了,当你发出kill的时候,机会是不会被杀死的。进程查杀是作为信号处理路径的一部分执行的,该路径是从内核到用户空间的返回转换代码调用的。如果进程正在等待内核螺旋锁,那么您将永远不会返回代码,因此进程不会退出。

此外,如果进程因内核OOPS而被终止,则所有投注都关闭 - 内核已处于不一致的状态,并且OOPS退出代码不会尽力清理内核中的任何锁线程可能一直在等待。

如果您正在讨论任何类型的用户空间自旋锁或信号量(包括IPC信号量的sem_*系列),否则它们不会被释放,因为没有信号量的锁拥有概念。

如果你在谈论的flock家庭文件锁定,或fcntl(F_SETLK, ...)咨询锁的,他们将被自动时绑定到该进程的文件任何同时关闭文件释放。因此,在大多数情况下使用flock是个不错的主意,但是,如果进程被终止,它将被释放。

如果你正在谈论一个进程本地pthread_mutex,它是没有意义的,因为互斥将随着进程停止存在。

如果你在谈论的共享内存段(在其中pthread_mutexattr_setpshared已经使用,使它可共享)的共享pthread_mutex,它会自动释放,只有当它也被标记为一个强大的互斥体,以pthread_mutexattr_setrobust - 但在重新使用之前必须标注一致;有关详细信息,请参阅pthread_mutex_consistent联机帮助页。

+0

非常感谢。我在谈论内核内部锁,因为我们想解除系统锁定错误。并且这些类型的锁在发生某些错误时会发生冲突,特别是自旋锁(非常具有破坏性!!) – silverbullettt 2012-03-25 14:47:18

+0

@silverbullet,如果您有内核死锁,您实际上无法杀死涉及的进程 - 杀死进程需要退出内核转换,因为SIGKILL信号在内核到用户空间的退出代码路径中处理。由于这个过程陷入僵局,它甚至不会那么做。 – bdonlan 2012-03-25 21:14:43

+0

是的,信号只会在内核到用户空间的退出代码路径中处理,所以我们打算采取非常规的意思 - Linux内核提供了一个force_sig(),如果这个函数可以按照我们的期望工作(发送一个发信号给一个进程并唤醒它),比我们解决它。 – silverbullettt 2012-03-26 00:48:15