实现代码
#include <iostream>
#include <vector>
#include <memory>
#include <mutex>
#include <thread>
class SharedData {
public:
static std::vector<int>& getData() {
static std::once_flag flag;
static std::unique_ptr<std::vector<int>> data;
std::call_once(flag, []() {
data = std::make_unique<std::vector<int>>();
// 在这里添加初始化逻辑,例如:
data->push_back(1);
data->push_back(2);
data->push_back(3);
});
return *data;
}
private:
SharedData() = default;
~SharedData() = default;
SharedData(const SharedData&) = delete;
SharedData& operator=(const SharedData&) = delete;
};
void threadFunction() {
std::vector<int>& data = SharedData::getData();
std::cout << "Thread accessed data: ";
for (int num : data) {
std::cout << num << " ";
}
std::cout << std::endl;
}
int main() {
std::thread t1(threadFunction);
std::thread t2(threadFunction);
t1.join();
t2.join();
return 0;
}
实现原理
std::once_flag
和std::call_once
:
std::once_flag
是一个结构体类型,用于控制std::call_once
的执行。它内部维护了一个状态,用于记录关联的函数是否已经执行过。
std::call_once
函数接受两个参数,第一个是std::once_flag
对象,第二个是一个可调用对象(如函数指针、lambda表达式等)。std::call_once
保证在多线程环境下,与给定的std::once_flag
关联的可调用对象只被调用一次,无论有多少线程同时尝试调用它。在上述代码中,std::call_once(flag, []() { /* 初始化逻辑 */ });
确保了data
的初始化代码只执行一次。
static
局部变量:
- 在
getData
函数中,data
被定义为static std::unique_ptr<std::vector<int>>
类型的局部变量。这种static
局部变量具有线程安全的初始化特性(C++11起)。结合std::call_once
,进一步保证了data
初始化的唯一性和线程安全性。
- 单例模式特性:
- 通过将类的构造函数、析构函数、拷贝构造函数和赋值运算符重载声明为私有或删除,确保
SharedData
类只能通过getData
函数来访问其唯一的静态数据成员,符合单例模式的思想,从而在多线程环境下安全地提供共享数据。