面试题答案
一键面试- 可能出现的线程安全问题:
- 由于多个线程同时调用
func
函数,而localVar
是静态局部变量,多个线程会同时对其进行自增操作。自增操作localVar++
不是原子操作,它实际上包含读取localVar
的值、增加该值、再将新值写回localVar
三个步骤。在多线程环境下,可能会出现一个线程读取了localVar
的值,还没来得及增加并写回时,另一个线程也读取了相同的值,导致最终增加的值比预期少,这就是数据竞争问题,会导致程序出现不可预测的结果。
- 由于多个线程同时调用
- 解决方法:
- 使用互斥锁(
std::mutex
): 在func
函数中使用std::mutex
来保护对localVar
的操作。修改后的代码如下:
- 使用互斥锁(
#include <iostream>
#include <mutex>
class A {
public:
static void func() {
static int localVar = 0;
static std::mutex mtx;
std::lock_guard<std::mutex> lock(mtx);
localVar++;
std::cout << localVar << std::endl;
}
};
这里使用std::lock_guard
在进入func
函数时自动锁定mtx
,在函数结束时自动解锁,确保在同一时间只有一个线程能够访问和修改localVar
。
- 使用原子变量(
std::atomic
): 将localVar
声明为std::atomic<int>
类型,std::atomic
类型的操作是原子的,不需要额外的锁机制。修改后的代码如下:
#include <iostream>
#include <atomic>
class A {
public:
static void func() {
static std::atomic<int> localVar(0);
localVar++;
std::cout << localVar << std::endl;
}
};
std::atomic<int>
的自增操作是原子的,所以不会出现数据竞争问题。