面试题答案
一键面试多线程环境下C++类的static成员变量可能遇到的问题
- 数据竞争:多个线程同时读写static成员变量,可能导致数据不一致。例如,一个线程读取static变量的值,另一个线程同时修改该值,会使得读取到的值不准确。
- 初始化问题:在多线程环境下,static成员变量的初始化顺序可能不确定,导致在使用时该变量还未正确初始化。
通过互斥锁确保多线程访问安全性
可以使用std::mutex
来保护static成员变量。每次访问static成员变量前,先锁定互斥锁,访问完成后解锁。
代码示例
#include <iostream>
#include <mutex>
#include <thread>
class MyClass {
public:
static int getStaticValue() {
std::lock_guard<std::mutex> lock(mutex_);
return staticValue_;
}
static void incrementStaticValue() {
std::lock_guard<std::mutex> lock(mutex_);
++staticValue_;
}
private:
static int staticValue_;
static std::mutex mutex_;
};
int MyClass::staticValue_ = 0;
std::mutex MyClass::mutex_;
void threadFunction() {
for (int i = 0; i < 1000; ++i) {
MyClass::incrementStaticValue();
}
}
int main() {
std::thread threads[10];
for (int i = 0; i < 10; ++i) {
threads[i] = std::thread(threadFunction);
}
for (auto& thread : threads) {
thread.join();
}
std::cout << "Final static value: " << MyClass::getStaticValue() << std::endl;
return 0;
}
在上述代码中:
MyClass
类有一个static
成员变量staticValue_
和一个static
的互斥锁mutex_
。getStaticValue
和incrementStaticValue
函数使用std::lock_guard
来自动管理互斥锁的锁定和解锁,确保在访问staticValue_
时的线程安全。- 在
main
函数中,创建10个线程同时调用incrementStaticValue
函数,如果没有互斥锁保护,最终的staticValue_
值将是不确定的,有了互斥锁保护后,可以得到正确的累加结果。