【发布时间】:2017-02-20 11:39:39
【问题描述】:
如果一个进程有三个线程,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 Unix 服务的 Windows,以防它依赖于平台,但我的兴趣是一般应该发生的事情。 https://technet.microsoft.com/en-us/library/bb463209.aspx.
【问题讨论】:
-
Windows 没有 pthreads,请编辑您的问题以阐明上下文。也许您的目标平台真的是 Cygwin 吗?还是您使用的是第三方库,例如 pthreads-win32?
-
... 在任何情况下,正确的答案几乎肯定是终止 T2 会导致未定义的行为,因为在 Windows 上终止线程几乎总是会导致未定义的行为。只是不要。
-
如果你使用pthreads-win32,注意
pthread_killis specifically documented“只支持零sig值,用于线程有效性检查”。 -
只有当你有一个进程共享的互斥锁时,健壮的互斥锁才有意义,因为强制线程终止本质上是危险的。如果您使用 pthread_cancel(),您应该使用取消状态和清理处理程序来修复状态并在退出线程之前解锁互斥锁。 (pthread_kill() 不会终止单个线程,除非您有一个调用 pthread_exit() 的信号处理程序,这是相当危险的。)由于 pthreads-win32 似乎不支持进程共享互斥锁,这使得整个问题变得不那么有趣。
-
@jilles 我想你几乎给了我我正在寻找的确切答案。如果我在 T2 上使用 pthread_cancel() 并且没有做任何其他事情,那么当 T1 释放时互斥锁会发生什么?
标签: c windows multithreading