当一个线程在等待互斥体时死亡会发生什么?

如果一个进程有三个线程T1,T2和T3,并且三个线程都试图获取互斥锁M1,我知道一个线程会获取互斥锁,另外两个将等待互斥锁的获取。

如果我使用pthread_mutexattr_setrobust()使线程健壮,那么我明白,如果T1持有M1,并且T1在释放之前终止,则M1,T2以EOWNERDEAD的返回值唤醒。 T2然后可以清理受保护资源的状态。

现在,如果T1拥有M1而T2和T3等待M1,会发生什么情况。 T2终止。 怎么了? 当T1释放M1时,互斥量是否直接到T3? T3是否获得EOWNERDEAD,还是只是看起来T3像没有发生过的事情,没有需要清理? 看起来T3应该只是采取M1,因为T2不能把线程变成不一致的状态。 任何答案? 这是一个我对知识兴趣的问题,而不是试图解决一个特定的问题,因此有必要进一步阅读这个问题的指引。

编辑:我不是想弄清楚如何做到这一点,而是我试图找出发生什么,一般pthread实现,当T2被终止或被取消(有兴趣在这两种情况下,只有开始了解它可能对结果的差异)。 它是否定义了行为?

我的目标平台是使用Windows Services for Unix的Windows,以防依赖于平台,但是我的兴趣在于应该发生什么。 https://technet.microsoft.com/en-us/library/bb463209.aspx 。

注意:我完全根据所写的标准来回答这个问题,而不是以个人经验或相关的专业知识。

取消pthread分为两种情况:

如果pthread被配置为延迟取消(这是默认),那么根据标准的文字读取,取消请求将不会被处理,直到互斥体被声明(或未被声明)之后,因为pthread_mutex_lock和朋友是不在可以取消的功能列表中,如标准第2.9.5节所示。

我不确定各种实现是否实际上是这样做的,因为这看起来是不可取的。 如果一个实现实际上允许取消而试图声明一个互斥体(也许是因为pthread_mutex_lock函数在内部使用了一个列出的可取消函数),我认为它会导致互斥体根据Jille的答案保持一致和无声,但是标准似乎并没有明确要求。

如果pthread配置为异步取消,则行为是未定义的:

pthread_cancel(),pthread_setcancelstate()和pthread_setcanceltype()函数被定义为异步取消安全。

本卷的POSIX.1-2008中没有其他函数需要异步取消安全。

如果某个线程启用了异步取消,并且在执行非异步取消安全的函数期间被取消,则行为是不确定的。

似乎没有可能终止一个单独的pthread。 从2.4.3节:

当信号传递给线程时,如果该信号的动作指定终止,停止或继续,那么整个过程将分别终止,停止或继续。

根据POSIX.1-2008tc1中的pthread_mutex_lock()的规范:

  • 如果pthread_mutex_lock()返回零或[EOWNERDEAD]线程将成为互斥量的所有者。
  • 当包含拥有线程(或者,拥有线程)的进程在拥有该互斥体时终止时,会发生错误[EOWNERDEAD]

在你的例子中, pthread_mutex_lock()对于T2是不成功的,因此T3将无错地获取M1。

你必须使用条件变量,使其完美的工作。 我复制下面粘贴一些文件。

条件变量允许线程同步到共享资源的值。 通常,条件变量被用作线程之间的通知系统。

例如,你可以有一个计数器,一旦达到一定数量,你想要一个线程来激活。 一旦计数器达到极限,激活的线程(或多个线程)将等待条件变量。 活动线程在这个条件变量上发信号通知其他线程在这个条件变量上等待/休眠; 从而导致等待线程唤醒。 如果您想要发送等待条件变量的所有线程唤醒,也可以使用广播机制。 从概念上讲,这是用伪代码的右图来建模的。

当等待条件变量时,等待应该在一个循环内,而不是由于虚假唤醒的简单if语句。 如果线程被唤醒,则不能保证是信号或广播呼叫的结果。

文档链接: http : //randu.org/tutorials/threads/