未解锁锁定的互斥锁
Posted
技术标签:
【中文标题】未解锁锁定的互斥锁【英文标题】:Not unlocking locked mutex 【发布时间】:2021-12-23 08:06:04 【问题描述】:您好,我是新手,我想知道我理解错了什么。我有一个程序:
#include <pthread.h>
pthread_mutex_t lock;
pthread_mutexattr_t att;
int main ()
pthread_mutexattr_init (&att);
pthread_mutexattr_settype (&att, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init (&lock, &att);
pthread_mutex_lock (&lock);
pthread_mutex_lock (&lock);
pthread_mutex_unlock (&lock);
PTHREAD_MUTEX_RECURSIVE 表示锁会记住被锁了多少次。但是这个程序仍然没有任何错误地完成。即使我根本不调用解锁......我会期待一些错误,我仍然锁定锁或类似的东西......它会以某种方式自动解锁吗? (我将我的代码编译为gcc main.c -pthread
)
【问题讨论】:
@G.M.,互斥体类型宏提供特定代码,而不是位掩码标志。您可以拥有PTHREAD_MUTEX_ERRORCHECK
或 PTRHEAD_MUTEX_RECURSIVE
,但不能同时拥有。实际上,这两个在理论上甚至都不兼容,因为它们在程序尝试锁定它已经锁定的互斥体的情况下提供了不同的行为。
【参考方案1】:
我希望我仍然锁定了一些错误
不。没有什么可以阻止进程终止,也不会抱怨进程在锁仍然被锁定时终止。这就像期待一个错误,因为您 malloc()
d 一个对象,但在进程终止之前没有释放它。就像因为您打开了一个文件但没有关闭它而期待一个错误一样。
锁——就像 malloc()d 对象占用的虚拟内存,就像打开的文件句柄一样——是独占进程的资源,当你杀死进程时,所有这些资源都会自动销毁/释放/释放/等。
P.S.,这可能是转向 C++ 的一个很好的理由,特别是 C++ 启用的 RAII design pattern。 RAII 是一种保证不会忘记打开文件、分配的对象、锁定的锁等的方法。
【讨论】:
感谢您的解释【参考方案2】:即使我根本不调用解锁......我会期待一些错误,我仍然锁定了锁或类似的东西
为什么?
程序在持有互斥锁的情况下终止并不是天生的错误。此外,即使程序确实出错,C 也不保证任何运行时诊断。有时您会在这种情况下得到诊断,但通常不会。
...它会自动解锁吗?
不,但这在示例中并不重要,因为互斥锁本身在程序终止时被破坏。
如果它是另一个进程也可以访问的进程共享互斥锁,那么进程在保持锁定状态时终止将是语义错误。但可能仍然不是您可以期望得到诊断的。
【讨论】:
非常感谢以上是关于未解锁锁定的互斥锁的主要内容,如果未能解决你的问题,请参考以下文章