当获取它的线程退出时,Mutex会发生什么?

Sad*_*ish 17 c multithreading pthreads

假设有两个线程,主线程和线程B(由main创建).如果B获得了一个互斥锁(比如pthread_mutex)并且在没有解锁锁的情况下调用了pthread_exit.那么互斥体会发生什么?它变得免费吗?

Sin*_*ion 17

不.互斥锁保持锁定状态.这种锁实际发生了什么取决于它的类型,你可以在这里这里阅读

  • @Hans:一般来说,没有。一个普通的互斥锁甚至不需要知道哪个线程锁定了它;必须获取和存储这些信息会使其不必要地变慢。当然,实现如何永久保留死线程的 id 并防止其重用而不会耗尽 id?POSIX 提供了专门的健壮互斥锁,如果您需要这种功能,您可以创建它们,但它们通常会慢得多并且使用更多的资源(可能包括用户空间和内核空间)。 (2认同)

R..*_*R.. 14

如果通过在调用之前设置正确的属性来创建强大的互斥锁pthread_mutex_init,则当持有锁的线程终止时,互斥锁将进入特殊状态,并且尝试获取互斥锁的下一个线程将获得错误EOWNERDEAD.然后,它负责清除互斥锁保护的任何状态,并调用pthread_mutex_consistent以使互斥锁再次可用,或者调用pthread_mutex_unlock(这将使互斥锁永久不可用;进一步尝试使用互斥锁将返回ENOTRECOVERABLE).

对于非健壮的互斥锁,如果锁定它的线程终止而未解锁,则互斥锁将永久不可用.根据标准(参见在Austin Group跟踪器上发布755的决议),互斥锁保持锁定状态,其正式所有权继续属于退出的线程,并且任何试图锁定它的线程都将死锁.如果另一个线程试图解锁它,那通常是未定义的行为,除非使用该PTHREAD_MUTEX_ERRORCHECK属性创建互斥锁,在这种情况下将返回错误.

另一方面,许多(大多数?)现实世界的实现实际上并不符合标准的要求.尝试从另一个线程锁定或解锁互斥锁可能会虚假成功,因为线程ID(用于跟踪所有权)可能已被重用,现在可能引用另一个线程(可能是发出新锁定/解锁请求的线程).至少glibc的NPTL已经表现出这种行为.