MST

星途 面试题库

面试题:C++中静态函数线程安全问题基础分析

在C++中,假设有一个类A,类中有一个静态函数func,其内部使用了一个静态局部变量,如下代码所示: ```cpp class A { public: static void func() { static int localVar = 0; localVar++; std::cout << localVar << std::endl; } }; ``` 当多个线程同时调用func函数时,可能会出现什么线程安全问题?如何解决这个问题?
24.3万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 可能出现的线程安全问题
    • 由于多个线程同时调用func函数,而localVar是静态局部变量,多个线程会同时对其进行自增操作。自增操作localVar++不是原子操作,它实际上包含读取localVar的值、增加该值、再将新值写回localVar三个步骤。在多线程环境下,可能会出现一个线程读取了localVar的值,还没来得及增加并写回时,另一个线程也读取了相同的值,导致最终增加的值比预期少,这就是数据竞争问题,会导致程序出现不可预测的结果。
  2. 解决方法
    • 使用互斥锁(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>的自增操作是原子的,所以不会出现数据竞争问题。