【问题标题】:POSIX thread exit/crash/exception-crash while holding mutexPOSIX线程退出/崩溃/异常崩溃,同时持有互斥锁
【发布时间】:2011-11-12 23:46:19
【问题描述】:

的情况下,POSIX 互斥体所有权是否存在明确定义的行为
  1. 线程退出
  2. 线程崩溃
  3. 线程因异常而崩溃

假设 thread-1 拥有一个互斥体。线程 2 正在等待获取相同的互斥锁。线程 1 进入 1/2/3 场景。对thread-2有什么影响?

PS : 我相信自旋锁的行为是,不解除线程 2 的阻塞,原因是受自旋锁保护的部分无论如何都处于不良状态。

【问题讨论】:

  • 它保持锁定状态。这是 c,所以运行时不会为你做任何事情,所以如果你自己不解锁它,它会保持锁定状态。

标签: c pthreads posix mutex


【解决方案1】:

如果您担心这些问题,Robust Mutexes 可能是您正在寻找的工具:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_setrobust.html

在拥有健壮互斥锁的线程在没有解锁的情况下终止后,下一个尝试锁定它的线程将获得EOWNERDEAD 并成为新的所有者。这表明它负责清理互斥锁保护的状态,并在解锁之前再次将其标记为与pthread_mutex_consistent 函数一致。在未将其标记为一致的情况下解锁它会使互斥锁处于永久不可恢复的状态。

请注意,使用健壮的互斥锁,所有锁定互斥锁的代码都必须意识到EOWNERDEAD 可能被返回。

【讨论】:

  • 但是在返回EOWNERDEAD 时要格外小心——任何受互斥锁保护的数据结构都可能处于不一致的状态。有关更详细的讨论,请参阅Understanding the consequences of WAIT_ABANDONED(尽管它指的是 Windows 互斥锁,它与 pthreads 互斥锁的语义略有不同,但帖子的主要观点仍然成立)。
  • 另外,请注意文档说“如果一个健壮的互斥锁的拥有线程在持有互斥锁时终止,则获取该互斥锁的下一个线程可能被通知由返回值终止 [EOWNERDEAD]"(强调我的)——返回 EOWNERDEAD 不是保证。只有在持有互斥锁的进程被终止的情况下,它才会说它应该返回EOWNERDEAD(在这种情况下,它必须是一个进程共享的互斥体)。
  • 感谢您的第二条评论。这是一个我不知道的非常重要的细节。还值得注意的是,甚至不需要实现来支持非进程共享互斥体的健壮属性。
【解决方案2】:

这真的很简单。如果您没有显式解锁互斥锁,它将保持锁定状态,无论发生了什么或为什么。这是 c,而不是 ruby​​ on rails 或 visual basic。

【讨论】:

  • 我不这么认为。 Windows 肯定会在案例 1 和案例 3 中进行一些清理。
  • 也许 Kevin 应该说“这是 POSIX,而不是 Windows。”
  • 在 windows 上最接近 posix 互斥锁的等价物是 CRITICAL_SECTION。 MSDN 页面显示“如果线程在拥有临界区所有权时终止,则临界区的状态未定义。”
猜你喜欢
  • 1970-01-01
  • 2011-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-26
  • 1970-01-01
  • 2011-05-17
  • 1970-01-01
相关资源
最近更新 更多