面试题答案
一键面试可能出现的问题
- 数据竞争(Data Race):多个线程同时读写
globalVec
时,可能会导致数据不一致。例如,一个线程正在写入数据,另一个线程同时读取,可能读取到不完整或错误的数据。 - 竞态条件(Race Condition):由于线程执行顺序的不确定性,可能会导致程序的行为出现不可预测的结果。例如,多个线程同时对
globalVec
进行插入操作,可能导致globalVec
的元素顺序不符合预期。
解决方案
- 使用互斥锁(Mutex):互斥锁可以保证在同一时间只有一个线程能够访问
globalVec
。
关键代码片段:
#include <iostream>
#include <vector>
#include <mutex>
#include <thread>
std::vector<int> globalVec;
std::mutex globalVecMutex;
void writeToGlobalVec(int value) {
std::lock_guard<std::mutex> lock(globalVecMutex);
globalVec.push_back(value);
}
int readFromGlobalVec(int index) {
std::lock_guard<std::mutex> lock(globalVecMutex);
if (index < globalVec.size()) {
return globalVec[index];
}
return -1; // 表示无效索引
}
int main() {
std::thread writer1(writeToGlobalVec, 1);
std::thread writer2(writeToGlobalVec, 2);
std::thread reader1([&] { std::cout << "Read value: " << readFromGlobalVec(0) << std::endl; });
writer1.join();
writer2.join();
reader1.join();
return 0;
}
- 使用原子操作(Atomic Operations):虽然
std::vector
本身不是原子类型,但可以对其某些操作进行原子化处理。例如,使用原子计数器来记录globalVec
的大小,以避免在读取和写入globalVec
时出现竞争条件。
关键代码片段:
#include <iostream>
#include <vector>
#include <atomic>
#include <thread>
std::vector<int> globalVec;
std::atomic<int> globalVecSize(0);
void writeToGlobalVec(int value) {
globalVec.push_back(value);
globalVecSize++;
}
int readFromGlobalVec(int index) {
if (index < globalVecSize.load()) {
return globalVec[index];
}
return -1; // 表示无效索引
}
int main() {
std::thread writer1(writeToGlobalVec, 1);
std::thread writer2(writeToGlobalVec, 2);
std::thread reader1([&] { std::cout << "Read value: " << readFromGlobalVec(0) << std::endl; });
writer1.join();
writer2.join();
reader1.join();
return 0;
}
这种方法虽然不能完全保证 globalVec
操作的原子性,但可以在一定程度上减少数据竞争的风险。对于复杂的 vector
操作,还是建议使用互斥锁来保证线程安全。