Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 当获取互斥体的线程退出时,互斥体会发生什么情况?_C_Multithreading_Pthreads - Fatal编程技术网

C 当获取互斥体的线程退出时,互斥体会发生什么情况?

C 当获取互斥体的线程退出时,互斥体会发生什么情况?,c,multithreading,pthreads,C,Multithreading,Pthreads,假设有两个线程,主线程和线程B(由主线程创建)。如果B获得了一个互斥锁(比如pthread_mutex),并且在没有解锁锁的情况下调用了pthread_exit。那么互斥锁会发生什么变化呢?它是免费的吗?不是。互斥锁仍处于锁定状态。这种锁的实际情况取决于它的类型,您可以了解它,或者如果在调用pthread\u mutex\u init之前通过设置正确的属性创建了一个健壮的互斥体,那么当持有锁的线程终止时,互斥体将进入一种特殊状态,下一个试图获取互斥锁的线程将获得一个错误EOWNERDEAD。然后

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

不是。互斥锁仍处于锁定状态。这种锁的实际情况取决于它的类型,您可以了解它,或者

如果在调用
pthread\u mutex\u init
之前通过设置正确的属性创建了一个健壮的互斥体,那么当持有锁的线程终止时,互斥体将进入一种特殊状态,下一个试图获取互斥锁的线程将获得一个错误
EOWNERDEAD
。然后,它负责清除互斥体保护的任何状态,并调用
pthread\u mutex\u consistent
使互斥体再次可用,或调用
pthread\u mutex\u unlock
(这将使互斥体永久不可用;进一步尝试使用它将返回
ENOTRECOVERABLE

对于非健壮互斥体,如果锁定互斥体的线程终止而未解锁互斥体,则互斥体将永久不可用。根据标准(请参阅Austin Group tracker上的解决方案),互斥锁保持锁定,其正式所有权继续属于退出的线程,任何试图锁定它的线程都将死锁。如果另一个线程试图解锁它,这通常是未定义的行为,除非互斥体是使用
PTHREAD\u mutex\u ERRORCHECK
属性创建的,在这种情况下将返回错误


另一方面,许多(大多数?)现实世界的实现实际上并不遵循标准的要求。尝试从另一个线程锁定或解锁互斥锁可能会错误地成功,因为线程id(用于跟踪所有权)可能已被重用,并且现在可能引用另一个线程(可能是发出新锁定/解锁请求的线程)。至少我们知道glibc的NPTL表现出这种行为。

哇,一个没有线程亲和力的“互斥体”?没有“被放弃”的错误状态?@Hans:一般来说,没有。正常的互斥锁甚至不需要知道是哪个线程锁定了它;必须获取和存储这些信息会使它变得毫无必要的缓慢。当然,实现如何永久保留死线程的id并防止其重用而不耗尽id?POSIX提供了专门的健壮互斥体,如果您需要这种功能,可以创建这种互斥体,但是它们通常会非常慢,并且会使用相当多的资源(可能是用户空间和内核空间)。因此,试图获取它已经拥有的互斥体的线程会死锁吗?艰难的编程。pthreads中有任何类型的重入锁定吗?@Hans:当然有:
pthread\u mutexttr\u settype(pthread\u MUTEX\u RECURSIVE)
@Hans:你需要一个递归互斥锁。普通互斥锁不是递归的。对递归互斥体的需求通常表明代码持有锁的时间过长,并且在负载下会产生非常糟糕的争用。