c++ - 局部静态变量初始化是线程安全的

标签 c++ c++11 c++14

假设我有一个包含三个静态函数的类,如下所示:

#include <vector>
#include <iostream>
using namespace std;
#include <thread>


class Employee
{

};

class client
{

public:
    void Doprocessing()
    {
        //is this thread safe in c++11/14
        static int i = CreateEmployee();

        //does it look good to use static variable like this to make it thread safe?
        static int k = ProcessEmploye();
    }

private:


    static int CreateEmployee()
    {
        static Employee * e = new Employee();
        InsertEmployee(e);
        return 1;
    }

    static int  InsertEmployee(Employee *e)
    {
        vec.push_back(e);
        return 1;
    }

    static int ProcessEmploye()
    {
        Employee* e = vec[0];
        //do something with e
        //...
        //.
        //Suppose 10 -20 lines 
        return 1;
    }


    static std::vector<Employee*> vec;
};

std::vector<Employee*> client::vec;

void func()
{
    client cobj;
    cobj.Doprocessing();
}

const int No_Of_Threads = 10;
int main() {


    std::thread * threadpointer = new std::thread[No_Of_Threads];

    std::srand(11);
    for (int i = 0; i < No_Of_Threads; i++)
    {
        threadpointer[i] = std::thread(func);
    }

    for (int i = 0; i < No_Of_Threads; i++)
    {
        threadpointer[i].join();
    }
    delete[] threadpointer;

    std::cout << " Good" << std::endl;
    return 0;
}

我的问题是:
1)如果我使用 static int i = Somefunc() 并且无论 somefunc 有多大,都会被调用一次并且它会线程安全吗?
2) 如果 1) 的答案是肯定的,那么对于程序员来说,使用 static int i = SomeFunc() 来实现上述目的是否看起来不错。

最佳答案

是的,它将是线程安全的,但仅从 C++11 开始。静态变量以线程安全的方式初始化,它们通常也称为魔术静态。

更多信息请参见这里:http://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables

If multiple threads attempt to initialize the same static local variable concurrently, the initialization occurs exactly once (similar behavior can be obtained for arbitrary functions with std::call_once). Note: usual implementations of this feature use variants of the double-checked locking pattern, which reduces runtime overhead for already-initialized local statics to a single non-atomic boolean comparison.

此外 - 在您的代码中您调用 CreateEmployee();在 static i 初始化期间,CreateEmployee( 也初始化了一个静态变量。这应该也可以,您可以在以下标准脚注中找到:

The implementation must not introduce any deadlock around execution of the initializer.

关于你的第二个问题,从你展示的代码中我看不出使用静态变量作为获得线程安全的方法是可以的。

您是否知道在函数体内将变量指定为静态变量只能让您分配一次?这意味着您的 CreateEmployee() 将始终返回相同的 Employee 实例。

关于c++ - 局部静态变量初始化是线程安全的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39487075/

相关文章:

c++ - 对全局常量使用 auto

c++ - 寻找设计模式以减少虚拟方法的重载

c++ - 模板基类实现一个默认实现

c++ - boost::any 库不编译: "Array used as initializer"错误

c++ - 为什么与花括号分隔的初始化程序一起使用的缩小转换不会导致错误?

c++ - undefined reference 错误

c++ - 为什么我不能使用 lambda 作为类中定义的集合的比较器?

c++ - Boost.Intrusive-恒定时间迭代器

c++ - 无法使用现代 OpenGL 渲染基本三角形

c++ - 为什么要区分通用算法的谓词和非谓词版本?