如果一个进程持有一些自旋锁或信号量,并意外退出(例如,被 linux 杀死),linux 会正确释放这些锁吗?如果linux不做这个工作,为什么?
1 回答
这取决于您正在谈论的锁的类型。
如果您正在谈论任何类型的内核内部锁,它们将被适当地释放(否则您的系统很快就会崩溃)。一般来说,这类锁不属于进程本身,而是由一些内部内核工作流拥有,并且在进程返回用户空间后通常不会保持锁定状态。
但是请注意,如果在您发出 kill 时内核已经死锁,则该进程很可能不会被杀死。进程终止是作为信号处理路径的一部分执行的,该路径是从内核到用户空间返回转换代码调用的。如果进程正在等待内核自旋锁,您将永远无法到达返回码,因此进程不会退出。
此外,如果进程因为内核 OOPS 而被杀死,那么所有的赌注都没有了——内核已经处于不一致的状态,并且 OOPS 退出代码不会非常努力地清理内核线程可能已经被锁定的任何锁当时持有。
如果您谈论的是任何类型的用户空间自旋锁或信号量(包括sem_*
IPC 信号量系列),不,它们不会被释放,因为信号量没有锁定所有权的概念。
如果您谈论的flock
是文件锁系列或fcntl(F_SETLK, ...)
建议锁,它们将在该进程中绑定到文件的任何文件描述符关闭时自动释放。因此,flock
在大多数情况下使用它是一个坏主意,但是是的,如果进程被杀死,它将被释放。
如果您谈论的是 process-local pthread_mutex
,那是没有意义的,因为互斥锁将与该进程一起不复存在。
如果您正在谈论pthread_mutex
共享内存段中的共享(pthread_mutexattr_setpshared
已用于使其可共享的内存段),则仅当它也被标记为健壮互斥体时才会自动释放,pthread_mutexattr_setrobust
但必须在之前标记为一致重复使用;有关详细信息,请参见pthread_mutex_consistent
手册页。