局部静态变量初始化是线程安全的 [英] Local Static variable initialization is thread safe
问题描述
假设我有一个具有以下三个静态函数的类:
Suppose I have a class with three static functions like this :
#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()达到上述目的看起来是否很好?
My questions are :
1)If I use static int i = Somefunc() and no matter how bulky somefunc is, will be called once and will it be thread safe ?
2) if answer of 1) is yes, Does it look good to programers eyes to use static int i = SomeFunc() for above purpose.
推荐答案
是的,它将是线程安全的,但仅从C ++ 11开始。静态变量以线程安全的方式初始化,通常也称为魔术静态。
Yes, it will be thread safe, but only since C++11. Static variables are initialized in thread safe way, they are often also called magic statics.
有关更多信息,请参见: http://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables
For more see here: http://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables
如果多个线程尝试同时初始化同一静态局部变量,则初始化仅发生一次(可以使用std :: call_once获得任意函数相似的行为)。
注意:此功能的常规实现使用双重检查的锁定模式的变体,从而将已经初始化的局部静态变量的运行时开销减少到单个非原子布尔比较。
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(
也会初始化一个静态变量。这也应该可以,您可以找到在下面的标准脚注中:
Also - in your code you call CreateEmployee(); during initialization of static i
, and CreateEmployee(
also initializes a static variable. This should also be OK, you can find in standard following footnote:
该实现不得在执行
初始化程序时引入任何死锁。
The implementation must not introduce any deadlock around execution of the initializer.
关于第二个问题,从您显示的代码中,我看不到使用静态变量作为获取线程安全的方法是可以的。
As to your second question, from the code you have shown I dont see that it is OK to use static variable as a way to gain thread safety.
您是否知道在函数体内将变量指定为静态变量只能分配一次吗?这意味着您的CreateEmployee()将始终返回相同的Employee实例。
Are you aware that specifying a variable as static inside function body allows you to assign it only once? This means your CreateEmployee() will always return the same Employee instance.
这篇关于局部静态变量初始化是线程安全的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!