【问题标题】:Why is locking a std::mutex twice 'Undefined Behaviour'?为什么将 std::mutex 锁定两次“未定义行为”?
【发布时间】:2012-06-23 22:37:58
【问题描述】:

据此article

如果您尝试从同一个线程锁定一个非递归互斥锁两次而不在其间解锁,您会得到未定义的行为。

我非常天真的头脑告诉我为什么他们不只是返回一个错误?这有什么必须是UB的原因吗?

【问题讨论】:

  • 您可能希望将 atomic_flag 与默认内存顺序一起使用。它没有数据竞争,也不会像 mutex 那样在多次解锁调用时抛出异常(并且无法控制地中止,我可能会添加......)。或者,有 atomic(例如 atomic[bool] 或 atomic[int](带三角括号,而不是 [])),它具有很好的函数,如 load 和 compare_exchange_strong。 cplusplus.com/reference/atomic/atomic_flagcplusplus.com/reference/atomic/atomic
  • 同样mutex 可能使用操作系统本机互斥锁来实现,那么不定义不同操作系统上可能有什么不同是有意义的,以便std::mutex 可以成为围绕操作系统提供的薄包装器互斥体。

标签: c++ c++11 mutex undefined-behavior


【解决方案1】:

因为它永远不会在正确的程序中发生,并且对从未发生的事情进行检查是浪费(并且要进行检查,它需要存储拥有线程 ID,这也是浪费)。

请注意,未定义允许调试实现抛出异常,例如,同时仍允许发布实现尽可能高效。

【讨论】:

  • 好 A,但是我认为好的 dbg 实现应该断言,因为 ppl 有时 :P 编写的代码会吃掉异常而不会产生太大的噪音。 :D
【解决方案2】:

未定义的行为允许实现做任何最快/最方便的事情。例如,非递归互斥锁的有效实现可能是单个位,其中锁定操作是通过循环中的原子比较和交换指令实现的。如果拥有互斥锁的线程试图再次锁定它,它将死锁,因为它正在等待互斥锁解锁,但由于没有其他人可以解锁它(除非存在一些其他错误,即某些不拥有它的线程将其解锁)线程将永远等待。

【讨论】:

    猜你喜欢
    • 2021-10-30
    • 2021-04-17
    • 2021-06-04
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 2016-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多