1. 确保线程安全的方法
- 使用互斥锁:在更新数据的线程中,获取互斥锁后进行数据更新操作,完成后释放互斥锁。在读取数据的线程中,获取互斥锁后通过指向常变量的指针读取数据,读完后释放互斥锁。
- 使用读写锁:更新数据的线程获取写锁进行数据更新,其他读取数据的线程获取读锁进行数据读取。读写锁允许多个线程同时读数据,但在写数据时会阻止其他线程读或写。
2. 代码框架示例
#include <iostream>
#include <thread>
#include <mutex>
#include <shared_mutex>
// 定义复杂数据对象类
class ComplexData {
public:
int data1;
double data2;
// 其他成员变量和成员函数
ComplexData() : data1(0), data2(0.0) {}
};
// 互斥锁用于保护数据对象
std::mutex dataMutex;
// 读写锁用于保护数据对象
std::shared_mutex rwMutex;
// 数据更新线程函数
void updateData(ComplexData* data) {
// 使用互斥锁
// std::lock_guard<std::mutex> lock(dataMutex);
// 使用读写锁
std::unique_lock<std::shared_mutex> lock(rwMutex);
// 模拟数据更新操作
data->data1++;
data->data2 += 1.0;
}
// 数据读取线程函数
void readData(const ComplexData* data) {
// 使用互斥锁
// std::lock_guard<std::mutex> lock(dataMutex);
// 使用读写锁
std::shared_lock<std::shared_mutex> lock(rwMutex);
// 读取数据
std::cout << "Data1: " << data->data1 << ", Data2: " << data->data2 << std::endl;
}
int main() {
ComplexData data;
const ComplexData* constPtr = &data;
// 创建更新数据的线程
std::thread updateThread(updateData, &data);
// 创建多个读取数据的线程
std::thread readThreads[5];
for (int i = 0; i < 5; ++i) {
readThreads[i] = std::thread(readData, constPtr);
}
// 等待更新线程完成
updateThread.join();
// 等待所有读取线程完成
for (auto& thread : readThreads) {
thread.join();
}
return 0;
}
3. 关键部分注释
- 互斥锁相关:
std::mutex dataMutex;
:声明一个互斥锁 dataMutex
,用于保护共享数据对象 ComplexData
。
std::lock_guard<std::mutex> lock(dataMutex);
:在 updateData
和 readData
函数中,使用 lock_guard
自动管理互斥锁的获取和释放。在构造 lock_guard
时获取互斥锁,在其析构时释放互斥锁。
- 读写锁相关:
std::shared_mutex rwMutex;
:声明一个读写锁 rwMutex
,用于更细粒度地控制对共享数据对象的访问。
std::unique_lock<std::shared_mutex> lock(rwMutex);
:在 updateData
函数中,使用 unique_lock
获取写锁,因为写操作需要独占访问权。
std::shared_lock<std::shared_mutex> lock(rwMutex);
:在 readData
函数中,使用 shared_lock
获取读锁,允许多个线程同时读取数据。
- 线程函数:
updateData
函数:负责更新共享数据对象,获取锁后进行数据更新操作。
readData
函数:负责读取共享数据对象,获取锁后通过指向常变量的指针读取数据,确保数据在读取过程中不会被修改。
- 主函数:
- 创建了一个
ComplexData
对象 data
,并使用指向常变量的指针 constPtr
指向它。
- 创建了一个更新数据的线程
updateThread
和五个读取数据的线程 readThreads
。
- 等待更新线程和所有读取线程完成后,程序结束。