假设有两个线程,主线程和线程B(由main创建)。如果B获得了一个互斥锁(比如pthread_mutex)并且在没有解锁锁的情况下调用了pthread_exit。那么互斥体会发生什么?它会免费吗?
答案 0 :(得分:16)
答案 1 :(得分:13)
如果通过在调用pthread_mutex_init
之前设置正确的属性来创建健壮的互斥锁,则当持有锁的线程终止时,互斥锁将进入特殊状态,并且下一个尝试获取互斥锁的线程将获得EOWNERDEAD
的错误。然后,它负责清除互斥锁保护的任何状态,并调用pthread_mutex_consistent
以使互斥锁再次可用,或调用pthread_mutex_unlock
(这将使互斥锁永久无法使用;进一步尝试使用互斥锁将返回{ {1}})。
对于非健壮的互斥锁,如果锁定它的线程在未解锁的情况下终止,则互斥锁将永久无法使用。根据标准(参见Austin Group跟踪器上issue 755的解析),互斥锁保持锁定状态,其正式所有权继续属于退出的线程,任何试图锁定它的线程都将死锁。如果另一个线程试图解锁它,那通常是未定义的行为,除非使用ENOTRECOVERABLE
属性创建互斥锁,在这种情况下将返回错误。
另一方面,许多(大多数?)现实世界的实现实际上并不符合标准的要求。尝试从另一个线程锁定或解锁互斥锁可能会虚假成功,因为线程ID(用于跟踪所有权)可能已被重用,现在可能引用另一个线程(可能是发出新锁定/解锁请求的线程)。至少glibc的NPTL已经表现出这种行为。