局部静态变量初始化是线程安全的
Local Static variable initialization is thread safe
假设我有一个类,其中包含如下三个静态函数:
#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)如果我使用静态int I = Somefunc(),无论Somefunc是多么庞大,将被调用一次,它将是线程安全的吗?2)如果1)的答案是肯定的,对于程序员来说,使用静态int i = SomeFunc()用于上述目的是否看起来不错。
是的,它将是线程安全的,但仅限于c++ 11之后。静态变量以线程安全的方式初始化,它们通常也被称为魔法静态。
更多信息请参见:http://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables
如果多个线程同时尝试初始化同一个静态局部变量,则初始化只发生一次(使用std::call_once可以获得任意函数的类似行为)。注意:此特性的通常实现使用双重检查锁定模式的变体,这将已经初始化的本地静态减少到单个非原子布尔比较的运行时开销。
也-在你的代码中你调用CreateEmployee();在初始化static i
时,CreateEmployee(
也初始化一个静态变量。这也应该没问题,你可以在标准的脚注中找到:
类的执行过程中不能引入死锁初始化器。
关于你的第二个问题,从你所展示的代码中,我不认为使用静态变量作为获得线程安全的一种方式是可以的。
你是否意识到在函数体内部指定一个变量为静态允许你只分配它一次?这意味着您的CreateEmployee()将始终返回相同的Employee实例。
相关文章:
- 如何将元素添加到数组的线程安全函数?
- C++中的线程安全删除
- 在std::thread中,joinable()然后join()线程安全吗
- 在c++队列中使用pop和visit实现线程安全
- 以线程安全的方式调用"QQuickPaintedItem::updateImage(const QImage&image)"(no QThread)
- 全局变量 多读取器 一个写入器多线程安全?
- 共享队列的线程安全
- boost::文件系统::recursive_directory_iterator多线程安全
- 以线程安全的方式转换 C/C++ 中时区名称字符串的时区偏移量
- 线程安全运算符<<
- 如何使缓存线程安全
- C++线程安全:如果只有一个线程可以写入非原子变量,但多个线程从中读取. 会遇到问题吗?
- 提升精神 V2 Qi 语法线程安全吗?
- asio 链对象线程安全吗?
- 线程安全队列 c++
- 提供对不同类型的数据(建议、代码审查)的线程安全访问的类
- 如何以线程安全的方式更改目录?
- 线程安全的引用计数队列C++
- 析构函数和线程安全
- 适用于大型数组的无复制线程安全环形缓冲区