gpt4 book ai didi

c++ - boost upgrade_lock 和 DCLP(双重检查锁定模式)

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:42:20 24 4
gpt4 key购买 nike

假设我们有以下(伪)代码:

using UpgradeLock = boost::upgrade_lock<boost::shared_mutex>;
using UpgradeToUniqueLock = boost::upgrade_to_unique_lock<boost::shared_mutex>;

boost::shared_mutex mtx;

void DeleteTable(<tbl>) {
UpgradeLock lock(mtx);
if (<the table exists>) {
UpgradeToUniqueLock up(lock); // (!)
// delete the table
}
}

假设两个线程刚刚进入这个函数并且都到达了语句,标记为(!)

我不知道接下来会发生什么。我有以下选择:

  1. 在第二个线程释放其 UpgradeLock 之前,一个线程无法获得独占访问权,但在它也获得独占访问权之前也无法获得独占访问权。死锁。
  2. 一个线程获得了独占访问权,而另一个线程在带有标记 (!) 的行处被挂起。

我想第二个选项可能会发生什么,但在这种情况下,即使有锁定的环境,我们也必须重新检查我们的数据没有被“外部”更改,即我们必须使用臭名昭著的 DCLP。我说得对吗?

我还没有找到任何关于它的合理信息,所以不要怪我太多:)

最佳答案

如果我理解正确,那么数字 2 将会发生。

如果您使用 Reader/Writer Locks您必须遵守假设的协议(protocol),只要多个读者共享锁,他们就只能进行读取访问。如果他们需要获得一些写权限,他们必须升级锁。

现在在你的情况下,可能会发生多个线程进入 if 语句并等待获取锁。没错,他们都会一个接一个地拿到锁。问题是,在获取锁之后,另一个线程可能已经删除了表。

这就是您可能需要双重检查锁定模式的原因。

从这里您有多种选择:

选项 1:检查表是否指向 NULL 并且什么都不做

选项 2:如果在调用 delete 之后指针设置为 NULLnullptr,只需再次调用 delete C++ 即可那(如果 delete 来自标准库)=> 什么都不做。仅供引用阅读:

http://en.cppreference.com/w/cpp/language/delete

if expression evaluates to a null pointer value, no destructors are called, and the deallocation function is not called.

  UpgradeLock lock(mtx);

if (<the table exists>)
{
UpgradeToUniqueLock up(lock); // (!)
if(<table still exists>)
{
// delete the table
// and set the pointer to nullptr
}
}

但根据选项 2,如果 delete 由 STL 实现,则以下代码片段就可以了: UpgradeLock 锁(mtx);

  if (<the table exists>) 
{
UpgradeToUniqueLock up(lock); // (!)
// delete the table
// and set the pointer to nullptr

}

选项 3:请改用 std::shared_ptrboost::shared_ptr。它们是同步的。因此,您甚至不需要锁,只需从多个线程调用 ptr.reset() 即可。

关于c++ - boost upgrade_lock 和 DCLP(双重检查锁定模式),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47264045/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com