c++ - 单例和多线程

标签 c++ multithreading singleton

我有以下类(class)

class Singleton
{
  private:

    static Singleton *p_inst;
    Singleton();

  public:

    static Singleton * instance()
    {
      if (!p_inst)
      {
        p_inst = new Singleton();
      }

      return p_inst;
    }
};

请详细说明在多线程环境下实现单例的注意事项。

最佳答案

在多线程中那个子句

if(!p_inst)
{
    p_inst = new Singleton();
}

实际上是 3 个独立的操作。您正在获取 p_inst 的值,设置 p_inst 的值并写入 p_inst 的值。所以 get-set-write 意味着你需要在 p_inst 周围加锁,否则你可以有 2 个线程创建每个线程使用的 Singleton 值。

假设您的 Singleton 有一个可变字段 val,您可以通过以下方式查看问题:

thread A -> p_inst is NULL
    thread B -> p_inst is NULL
       thread A -> set to Singleton (1)
           thread B -> set to Singleton (2)
              thread C -> p_inst is Singleton (2)
                  thread A -> set val to 4
                      thread B -> set val to 6
                         thread C -> get val (it's 6)
                             thread A -> get val (it's 4!!)

你看到了吗?有 2 个 Singleton 拷贝在四处漂浮,两者都不知道对方。检查 Singleton 的第三个线程只会看到最后的分配。但是通过锁定,您可以防止多重赋值和这些类型的问题。

关于c++ - 单例和多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3069255/

相关文章:

function - 检查函数的参数是否为函数

c++ - 数组中的严格别名规则

c++ - C++11 中 unique_ptr 的延迟初始化

c++ - Automake 库工具 'No rule to make target'

c++ - 为什么 Qt .pro 文件会为平台提供错误,即使未选择或提及它也是如此?

c++ - std::mutex 顺序一致吗?

java - 在 public void method() 内的 for 循环中创建新线程

java - 如何打印出当前在特定非线程类上运行的线程名称?

java - 如何从firebase实时数据库获取数据并将其设置为Singleton类

c++ - 如何不使用单例?