【问题标题】:std::lock() equivalent for boost::shared_mutex?std::lock() 等效于 boost::shared_mutex?
【发布时间】:2014-02-02 00:08:14
【问题描述】:

我有许多对象,每个对象都与一个 boost::shared_mutex 相关联(我需要共享/唯一锁定功能)。

在代码中的某些情况下,我需要一次获得多个对象的唯一所有权。

for (FileMetaData* entry : smd->fileSet) {
    entry->fileMutex.lock();
}

// some critical work

for (FileMetaData* entry : smd->fileSet) {
    entry->fileMutex.unlock();
}

当不同的线程试图获取不同的锁时,这样做会导致死锁。

我发现 std::lock () 适合我的用例。但是 boost::shared_mutex 有等价的吗?

编辑:

关于有序锁定模式,它并不完全适合我的情况:

T1 lock (C,D,E)
T2 wants to lock (B,D), but can only obtain the lock for B
T1 spawns T3 which works on (B,C), it stuck when obtaining the lock for B

所以问题是当 T1 生成 T3 时需要对 B 进行额外的锁定,这破坏了有序锁定模式。我认为如果 T2 在 D 不可锁定时不为 B 持有锁,则可以解决此问题,本质上是 std::lock 所做的。

【问题讨论】:

  • 如果您一次知道需要哪些锁——也就是说,在开始锁定之前,您已经掌握了整套锁——只需使用任何标准对锁进行排序并按该顺序锁定即可。只要所有线程都遵循相同的锁顺序,它们就永远不会死锁。 (这有时被称为“有序锁定模式”。)
  • @Nemo:这里是各种多锁算法的性能对比,包括排序算法:howardhinnant.github.io/dining_philosophers.html

标签: c++ multithreading boost boost-thread


【解决方案1】:

您可以使用std::lock(或等效的boost::lock,统称为“锁定功能”)来执行共享所有权锁定以及排他锁定,具体取决于您传递的要锁定的内容 - 任何Lockable 都可以.例如,如果您想在独占模式下锁定两个std::mutex/boost::mutexs A, Bboost::shared_mutex SM,您只需将三个传递给std::lock

std::lock(A, B, SM);

如果您想在共享所有权模式下锁定SM,您可以为其创建一个未锁定的boost::shared_lock 并将那个传递给锁定函数:

boost::shared_lock<boost::shared_mutex> bsl{SM, boost::defer_lock};
std::lock(A, B, bsl);

在与您的问题无关的注释 - 样式偏好 - 我更喜欢始终构建 RAII 锁以传递到 std::lock,所以我不能搞砸解锁,所以我实际上会写:

auto alk = boost::make_unique_lock(A, std::defer_lock);
auto blk = boost::make_unique_lock(B, std::defer_lock);
// boost::make_shared_lock(), where are you?!?
boost::shared_lock<boost::shared_mutex> bsl{SM, boost::defer_lock};
std::lock(alk, blk, bsl);

【讨论】:

  • 谢谢。我还有一个问题。在我的示例代码中,您可以看到每个互斥体都存储在一个 FileMetaData 结构中,该结构有一个位于 fileSet 中的指针。我应该如何提取这些互斥体成为 std::lock 的参数?
  • 除了 Casey 的帖子,请注意 C++14 已经包含 std::shared_mutex 和 std::shared_lock,这与 boost 几乎相同。 Clang/Gcc 已经实现了。
  • @jeremy 如果您知道编译时互斥锁的数量,您可以执行许多不同的模板技巧。在哪里构建一个 constexpr 对象并将其作为参数传递给 std::lock。如果互斥锁的数量是单独的运行时提升锁,则接受一对迭代器来表示 vector 或 vector 阅读此答案stackoverflow.com/a/21106127/1943599
猜你喜欢
  • 2021-08-30
  • 1970-01-01
  • 2012-12-27
  • 1970-01-01
  • 2013-06-30
  • 2011-03-19
  • 2013-08-27
  • 2020-11-17
  • 1970-01-01
相关资源
最近更新 更多