如何在构造函数中正确使用call_once()?

时间:2018-05-04 07:16:16

标签: c++ multithreading

以下program尝试在构造函数中使用 call_once ()。它是Stroustrup在“CPL”,4中提供的示例的修改。

class X
{
private:
   static int data;
   static once_flag initdata_flg;

   static void init();

public:
   X()
   {
      call_once(initdata_flg, init);

      cout << "** diagnostic: X::data initialized"
           << endl; 
   }

   int getdata() const
   {
      return data;
   }
};


/** class X static members ...
    (static members must be defined 
    outside the class **/
int X::data;
once_flag X::initdata_flg;

void X::init()
{
   data = 915;
}


/// declarations ...
void construct();

/// implementation ...

int main()
{
   thread t1 {construct};
   thread t2 {construct};

   t1.join();
   t2.join();
}

void construct()
{
    X x;
}


输出如下:

** diagnostic: X::data initialized
** diagnostic: X::data initialized

诊断出现两次,而不是一次。显然,这不是如何在构造函数中正确使用 call_once ()。

为此,我需要在 construct()函数中使用 call_once ()。那不是我想要做的。我想在构造函数中使用 call_once ()。

这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:4)

您在consturctor中发出诊断,而不是init。当然构造函数会运行两次;它将始终为您创建的每个对象运行一次。但是,只有一个call_once的来电实际上会调用init,您可以通过移动诊断输出来验证{。}}。

[Live example]