单例和多线程

ron*_*nan 5 c++ singleton multithreading

我有以下课程

class Singleton
{
  private:

    static Singleton *p_inst;
    Singleton();

  public:

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

      return p_inst;
    }
};
Run Code Online (Sandbox Code Playgroud)

请详细说明在多线程环境中实现Singleton时采取的预防措施.

whe*_*ies 7

在多线程中的那个子句

if(!p_inst)
{
    p_inst = new Singleton();
}
Run Code Online (Sandbox Code Playgroud)

实际上是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!!)
Run Code Online (Sandbox Code Playgroud)

你看?有一个Singleton浮动的副本,其中两个都不知道另一个.检查的第三个线程Singleton只会看到最后一个分配.但是通过锁定,您可以防止多次分配和这些类型的问题.

  • @ronan:是的,不要使用这种"单身"的反模式. (3认同)
  • 您可以使用静态变量而不是指针.这不是"懒惰",但它会避免你的施工问题.另一方面,除非你知道你在做什么,否则永远不要让单身人士变得可变.保留它,例如套接字池,线程池和其他不受应用程序控制的操作系统相关资源. (2认同)

Pup*_*ppy 5

在分配或读取指针之前,您必须使用互斥锁并锁定指针,这使得这个设计模式变得缓慢(并且非常简单).