【问题标题】:Is the default constructor thread-safe in C++?C++ 中的默认构造函数是线程安全的吗?
【发布时间】:2016-05-20 10:20:53
【问题描述】:
class log_String {
  //These are private!
  std::vector<std::string> list;
  std::mutex m;
  log_String& operator=(const log_String &source); //Operatore assegnazione
  log_String(const log_String &source);

public:
  log_String() {}; // <---- is this thread_safe?

  void add(std::string string) {
    std::lock_guard<std::mutex> l(m);
    list.push_back(string);
  }

  void printFile(std::string file) {
    std::lock_guard<std::mutex> l(m);
    std::ofstream myfile;

    myfile.open(file);
    for (auto iterator = list.begin(); iterator != list.end(); ++iterator) {
        myfile << *iterator << "\n";
    }
  }
};

log_String() {} 线程安全吗? 我认为即使许多线程同时调用log_String() {} 这应该不是问题吗?我弄错了吗? 如果我错了,可能的解决方案可能是定义它private 并保护获取新锁的新对象的实例化?

【问题讨论】:

  • 这个问题没有意义。构造函数在对象的生命周期开始之前 运行。一个不存在的对象如何同时被多个线程访问?
  • @KerrekSB 您的评论应该是一个答案!作为旁注:我问了一个关于对象生命周期是如何开始的问题(stackoverflow.com/questions/20409500/…)并得到了一些有趣的答案。标准中的“初始化完成”是什么意思? :)
  • @GeorgeAl:什么?如何?什么时候?
  • @mantler:表示第一个构造函数已经返回。
  • @KerrekSB,仅供参考stackoverflow.com/a/10586040/6271671

标签: c++ multithreading default-constructor


【解决方案1】:

log_String() 基本上是一个函数,但它也是一个构造函数。因此,实际上它在对象创建期间的调用也意味着递归地调用所有成员变量(具有构造函数)的构造函数,以及所有基类的构造函数,以及它们的成员变量的构造函数。

所以你需要考虑所有被调用的函数。两个成员变量,listm,应该有线程安全的构造函数,因为它们来自标准库,虽然我没有从标准中检查(草稿应该可以免费下载,如果你想检查自己),如果他们没有线程安全的构造函数,事情会很疯狂。那么就没有基类,你的构造函数中也没有代码。

结论,它是线程安全的,因为里面没有任何东西,这会导致问题“即使许多线程同时调用 log_String()”。没有可见的共享数据或其他共享资源,如果成员变量中隐藏了任何共享数据,则可以信任它们安全地完成。

编写线程不安全的公共构造函数可能被认为是愚蠢的,甚至是邪恶的。尽管如此,如果您有来自 3rd 方库的成员变量或基类,或者只是您自己的类型,并且您不能 100% 确定它们的质量,那么停下来思考一下这种愚蠢是否已经完成是值得的.


一个可能编写的示例代码,尤其是用于调试目的,并且 会使事情变得线程不安全:

private:
    static unsigned static_counter;

public:
    log_String() {
        ++static_counter; // not atomic operation! potential data race!
    };

为了完整性:对上述代码的修复是简单地使用std::atomic&lt;unsigned&gt; 作为计数器。更复杂的情况可能需要静态互斥锁(如果您使用的是旧的蹩脚编译器(至少是 MSVC2010),可能会有不可避免的静态数据竞争条件)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-05
    • 2012-06-30
    • 1970-01-01
    • 2013-03-05
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    相关资源
    最近更新 更多