MST

星途 面试题库

面试题:C++ static函数线程安全实现与优化

假设你正在开发一个多线程应用,其中有一个static函数频繁被调用。请描述如何设计该函数以确保线程安全,并且在保证线程安全的前提下尽量优化性能。要求给出具体的实现思路及涉及到的C++ 特性。
38.4万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 实现思路
    • 使用互斥锁(Mutex):在static函数中,使用互斥锁来保护共享资源。当一个线程进入函数时,先锁定互斥锁,函数执行完毕后再解锁互斥锁。这样可以保证同一时间只有一个线程能够执行函数中的关键代码段,从而确保线程安全。
    • 减少锁的粒度:如果函数中有部分代码不涉及共享资源的操作,可以将这部分代码放在锁的保护范围之外,以提高性能。例如,如果函数中有一些初始化操作不依赖共享资源,那么可以先执行这部分初始化,然后再锁定互斥锁进行共享资源相关的操作。
    • 考虑读写锁(如果适用):如果static函数主要是读取共享资源,而写操作较少,可以使用读写锁(std::shared_mutex 等)。多个线程可以同时获取读锁来读取共享资源,只有在进行写操作时才需要获取写锁,这样可以提高并发读的性能。
  2. 涉及到的C++ 特性
    • C++11线程库
      • 互斥锁相关std::mutex是C++11引入的基本互斥锁类型。可以在类中定义一个std::mutex成员变量,在static函数中使用std::lock_guard<std::mutex>(RAII风格)来自动管理锁的获取和释放。例如:
class MyClass {
private:
    static std::mutex mtx;
public:
    static void myStaticFunction() {
        std::lock_guard<std::mutex> lock(mtx);
        // 这里是需要保护的共享资源操作代码
    }
};
std::mutex MyClass::mtx;
 - **读写锁相关**:`std::shared_mutex` 是读写锁类型,`std::unique_lock<std::shared_mutex>` 用于获取写锁,`std::shared_lock<std::shared_mutex>` 用于获取读锁。例如:
class MySharedData {
private:
    static std::shared_mutex mtx;
    static int data;
public:
    static int readData() {
        std::shared_lock<std::shared_mutex> lock(mtx);
        return data;
    }
    static void writeData(int newData) {
        std::unique_lock<std::shared_mutex> lock(mtx);
        data = newData;
    }
};
std::shared_mutex MySharedData::mtx;
int MySharedData::data = 0;
  • RAII(Resource Acquisition Is Initialization)std::lock_guardstd::unique_lockstd::shared_lock 都遵循RAII原则。它们在构造时获取锁,在析构时释放锁,这样可以避免因为异常等情况导致锁没有正确释放的问题,提高代码的健壮性。