【问题标题】:Why does boost's interprocess_condition deadlock in notify_one?为什么 boost 的 interprocess_condition 在 notify_one 中会死锁?
【发布时间】:2017-12-12 23:25:09
【问题描述】:

This is a link to an MCVE that demonstrates the deadlock

它包含五个部分:

  1. SharedEvent 是存储在共享内存中的 AutoResetEvent 的实现。

  2. CreatedSharedEvent 创建一个命名的共享内存对象,其中分配了一个 SharedEvent。它提供了一个访问器方法,该方法返回对 SharedEvent 的引用。

  3. OpenedSharedEvent 打开已在其中分配 SharedEvent 的命名共享内存对象。它还提供了一个访问器方法,该方法返回对 SharedEvent 的引用。

  4. 使用 CreatedShareEvent 创建 SharedEvent 并每 2 秒设置一次事件的服务器控制台应用程序。每次设置事件时都会打印一条消息。

  5. 使用 OpenedShareEvent 打开共享事件并在循环中等待事件的控制台应用程序。每次等待调用返回时,它都会打印一条消息。

重现问题:

  1. 运行服务器。观察每 2 秒打印一次的消息。

  2. 运行客户端。观察每 2 秒打印一次的消息。

  3. 关闭客户端。观察服务器停止打印消息。它在 interprocess_condition::notify_one() 中被阻塞

【问题讨论】:

  • 再次you come to us with a lot of prose, and no code。 “什么可能导致僵局” - 很多事情。如果我们可以see your code,我们更有可能看到哪个。
  • 这次等你发SSCCEMCVE。链接告诉你如何。我之前的回答向您展示了如何。
  • 我在我编辑的问题中提供了一个指向 MCVE 的链接
  • 从我目前的调查来看,罪魁祸首实际上可能不是对 notify_one 的调用。真正的 notify_one 试图去拿锁,但是死锁似乎是因为持有锁的进程被关闭了,而锁没有被释放。如果我是对的,那么只要剩余进程中的代码尝试获取锁,就会出现这个问题。所以我正在考虑改写这个问题。当进程存在时,是否可以自动释放 boost::interprocess::interprocess_mutex ?如果不是,那是否意味着我必须使用另一个互斥类进行同步?

标签: c++ boost condition-variable interprocess


【解决方案1】:

问题原因同here描述的一样:

boost 进程间的这种使用不能用于进程可能崩溃但仍持有锁的情况。

我将发布一个不同的问题,看看是否有人发现了 boosts condition_variable 和 interprocess_mutex 的良好替代品。

【讨论】:

  • 我也得出了同样的结论。自从您发布 SSCCE 以来,我一直在对这件事进行压力测试。除非我强制终止客户端,否则我不能让它失败。我已经运行服务器数小时,每 1 毫秒发送一条消息,同时有 52 个客户端在收到 50..250 条消息后自愿关闭。只有当我开始偶尔在执行过程中杀死客户端(它们重生)时,我才会看到服务器锁定。否则,服务器会持续运行数小时并发送数百万条消息(例如 446 分钟和发送 25,608,540 条消息)
  • 我目前正在使用替代同步原语运行相同的压力测试。 [目前在 linux 上。]
  • 正如预期的那样,使用named_mutexnamed_condition 并不能缓解问题。我在 12 分钟内锁定了它,此时服务器确实挂在了notify_one。感兴趣的代码:gist.github.com/sehe/812b11ab5b9bc64804296d29f8d6e20a
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-31
  • 2012-04-19
  • 1970-01-01
  • 2021-12-30
  • 1970-01-01
  • 2015-03-09
  • 2019-12-27
相关资源
最近更新 更多