c++ - 成员函数中的静态变量可以是线程安全的吗?

标签 c++ multithreading

我正在实现与问题here非常相似的东西.

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

我知道在多线程处理中使用静态变量通常是一个坏主意。如果两个线程同时创建 Window 实例,flagInit 可能会因数据竞争而无法工作。但 Singleton 类也不能为我完成这项工作,因为我想创建该类的多个实例。

Window toolTip, mainWindow;

如果我在初始化部分添加互斥体,这是否会使其线程安全?另外,这样做是一个好的做法吗?

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() 来自其他人的库,所以我无法对其执行任何操作

最佳答案

有一个工具专门用于此目的:std::call_once :

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

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

从技术上讲,您仍然可以使用静态来完成此操作,因为 C++11 使它们的初始化成为线程安全的:

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

关于c++ - 成员函数中的静态变量可以是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62317531/

相关文章:

将时间(NULL)转换为本地时间的 C++ 函数

c++ - 如何在这个 c++ 数据结构中处理快速插入-删除操作?

java - 获取 FinalizedDeleatedExecutorService 的状态

java - 所有线程结束后打印数据

java - Java TCP 聊天客户端中的多线程/IO 流问题

c++ - 赋值重载 : why does using the same object cause problems in the program?

c++ - 我的 Boost Phoenix lambda 有什么问题?

c++ - 内存文件 : Adding an int offset?

python - 运行的 uwsgi 线程过多

java - 有没有更好的方法来重新启动java线程?