面试题答案
一键面试分析
- 存在线程安全问题:
- 在
addElement
函数中,if (vec.size() < 10)
检查和获取锁mtx
这两个操作不是原子的。 - 假设线程A检查到
vec.size() < 10
,但在获取锁之前,线程B也进行了检查,同样发现vec.size() < 10
。 - 然后线程A获取锁并添加元素,接着线程B获取锁也添加元素,这样可能导致
vec
的元素数量超过10,违反了原本的设计意图。
- 在
修改方法
- 修改后的代码如下:
#include <vector>
#include <mutex>
class ComplexClass {
private:
std::vector<int> vec;
std::mutex mtx;
public:
void addElement(int num) {
std::unique_lock<std::mutex> lock(mtx);
if (vec.size() < 10) {
vec.push_back(num);
}
}
};
- 解释:
- 使用
std::unique_lock<std::mutex> lock(mtx);
在函数开始就获取锁,这样在检查vec.size() < 10
和添加元素vec.push_back(num)
这两个操作过程中,其他线程无法访问vec
,从而确保了线程安全。 std::unique_lock
相较于直接使用mtx.lock()
和mtx.unlock()
更加安全和灵活,它在析构时会自动释放锁,避免了因异常等情况导致锁未释放的问题。
- 使用