C++ C+中的默认构造函数是线程安全的+;? 类日志\u字符串{ //这些是私人的! std::向量表; std::互斥m; log_String和operator=(const log_String和source);//operator assignazone 日志字符串(常量日志字符串和源); 公众: log_String(){};//
C++ C+中的默认构造函数是线程安全的+;? 类日志\u字符串{ //这些是私人的! std::向量表; std::互斥m; log_String和operator=(const log_String和source);//operator assignazone 日志字符串(常量日志字符串和源); 公众: log_String(){};//,c++,multithreading,default-constructor,C++,Multithreading,Default Constructor,log_String()基本上是一个函数,但它也是一个构造函数。因此,实际上,在对象创建期间,它的调用意味着也递归调用所有成员变量(具有构造函数)的构造函数,以及所有基类的构造函数及其成员变量的构造函数 你需要考虑所有被调用的函数。这两个成员变量列表和 M,应该有线程安全的构造函数,因为它们来自标准库,而我没有从标准中检查(草案应该是可自由下载的,如果你想检查一下自己),如果没有线程安全的构造函数,事情会变得很疯狂。然后你的构造函数中就没有基类,也没有代码 结论,它是线程安全的,因为其中没有任何
log_String()
基本上是一个函数,但它也是一个构造函数。因此,实际上,在对象创建期间,它的调用意味着也递归调用所有成员变量(具有构造函数)的构造函数,以及所有基类的构造函数及其成员变量的构造函数
<>你需要考虑所有被调用的函数。这两个成员变量<代码>列表和<代码> M<代码>,应该有线程安全的构造函数,因为它们来自标准库,而我没有从标准中检查(草案应该是可自由下载的,如果你想检查一下自己),如果没有线程安全的构造函数,事情会变得很疯狂。然后你的构造函数中就没有基类,也没有代码
结论,它是线程安全的,因为其中没有任何内容,“即使多个线程同时调用log_String()”,也会导致问题。没有可见的共享数据或其他共享资源,并且如果成员变量中隐藏有任何共享数据,则可以放心安全地完成这些操作
编写线程不安全的公共构造函数可能被认为是愚蠢的,甚至是邪恶的。不过,如果您有来自第三方库的成员变量或基类,或者只是您自己的类型,并且您对它们的质量没有100%的把握,那么停下来想想是否已经犯了这种愚蠢的错误是值得的
一个可能会合理编写的示例代码,特别是用于调试目的的代码,它会使线程不安全:
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";
}
}
};
为了完整性:上述代码的修复方法是简单地将
std::atomic
用于计数器。更复杂的情况可能需要静态互斥体(如果您使用的是旧的蹩脚编译器(至少是MSVC2010),它可能会不可避免地存在与静态数据的争用条件).这个问题没有意义。构造函数在对象的生命周期开始之前运行。不存在的对象如何能被多个线程同时访问?@KerrekSB您的评论应该是答案!作为旁注:我问了一个关于对象生命周期如何在()之前开始的问题,并得到了一些有趣的答案。您的回答是什么“初始化完成”在标准中的意思是:)@GeorgeAl:什么?如何?何时?@mantler:这意味着第一个构造函数已返回。@KerrekSB,仅供参考
private:
static unsigned static_counter;
public:
log_String() {
++static_counter; // not atomic operation! potential data race!
};