gpt4 book ai didi

c++ - 在 C++11 之前的 C++ 中实现 Double Check Lock Pattern 安全吗

转载 作者:太空狗 更新时间:2023-10-29 21:14:01 26 4
gpt4 key购买 nike

class SelfTesting
{
private:
char * pChar;
SelfTesting()
{
pChar = new char[1024 * 1024 * 1024];
}
public:
static SelfTesting * pSelf;

static SelfTesting& GetInst()
{
if (!pSelf)
{
boost::lock_guard<boost::mutex> lock(g_boost_mutex);
if (!pSelf)
{
pSelf = new SelfTesting;
}
}
return *pSelf;
}
};

一般来说,我知道问题是由以下原因引起的:

1. allocate memory for `SelfTesting`
2. store the pointer to the allocated memory in `pChar`
3. initialize `SelfTesting`
  1. 如果其他线程触及步骤 2 和步骤 3 之间的指针,则会发生数据竞争条件。 From
  2. 如果指针复制不是原子的,数据竞争条件也会发生。 From

我知道我可以使用局部静态变量在 C++11 中实现这个模式。我的问题是当我在 C++11 之前使用 C++ 标准时,上面的实现是线程安全的还是未定义的。 boost::mutex 是否确保 pSelf 会在 lock 失效后更新?

最佳答案

正如所写,此模式在任何版本的 C++ 中都不安全。在 C++11 术语中,您在 pSelf 的外部读取和 pSelf 的写入之间存在数据竞争。

一般来说,在 C++11 之前的版本中,多线程代码的安全性是无法保证的。 C++11 最重要的一点是,它在 C++ 执行的抽象模型中引入了可能首先执行多个线程的想法。在此之前,对于多线程执行绝对没有任何保证,因为这个概念不存在。就标准而言,任何拥有多个线程的情况都是未定义的,因为它没有定义线程是什么。

这基本上意味着您在 C++98 中编写的任何多线程代码完全取决于您使用的特定实现。尽管在 C++11 的开发过程中,在各种编译器中发现了一些行为(尤其是优化),但在主流编译器中您可以依赖这些行为,这些行为在存在多个线程时实际上并不安全。

但这都无关紧要,因为您编写的代码在我所知道的任何编译器中都无法保证是安全的。使用 Visual C++,您可以通过使 pSelf volatile(VC++ 处理的 volatile 变量有点像原子)来使其安全,但那不会没有在 GCC 工作过。在 GCC 中,您必须使用原子内部函数或 Boost.Atomic 库。

关于c++ - 在 C++11 之前的 C++ 中实现 Double Check Lock Pattern 安全吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42108725/

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