Can static variables in member functions be thread safe?

Viewed 79

I am implementing something very similar to the question here.

Window::Window()
{
  static bool flagInit = true;
  if (flagInit)
  {
    doInit(); // doInit should be called only once. 
    flagInit = false;
  }  
  createWindow()
}

I understand that using static variables can generally be a bad idea when it comes to multithreading. If two threads create Window instance at the same time, flagInit might fail to work due to data race. But Singleton class won't do me the job either, since I want to create multiple instance of the class.

Window toolTip, mainWindow;

If I add a mutex to the initialization part, does that make it thread safe? Also, is that a good pratice to do so?

Window::Window()
{
  {
    std::scoped_lock<std::mutex> lock(mutex);
    static bool flagInit = true;
    if (flagInit)
    {
      doInit(); // doInit should be called only once. 
      flagInit = false;
    }  
  }
  createWindow()
}

PS doInit() comes from someone else's library so I cannot do anything to it

1 Answers

There's a tool exactly for this: std::call_once:

class Window
{
  static std::once_flag flagInit;
  // ...
};

Window::Window()
{
  std::call_once(flagInit, doInit); // Note: can throw
  createWindow();
}

You can also technically still accomplish this with statics since C++11 made their initialization thread-safe:

Window::Window()
{
  static bool flagInit = (doInit(), false);
  createWindow()
}
Related