MST

星途 面试题库

面试题:C++多线程环境下const成员函数的状态保护

在多线程环境下,C++的const成员函数如何保证对象状态的一致性和线程安全性?假设存在一个类,其const成员函数会访问共享资源,你将如何设计和实现以确保状态保护不受多线程干扰,包括但不限于锁机制、原子操作等技术的应用,阐述具体思路并给出关键代码片段。
36.4万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

思路

  1. 锁机制:使用互斥锁(std::mutex)来保护共享资源。在进入const成员函数时锁定互斥锁,离开函数时解锁,这样可以保证同一时间只有一个线程能访问共享资源。
  2. 原子操作:对于简单的共享资源(如计数器等),可以使用原子类型(std::atomic),它提供了原子的读、写和修改操作,无需额外的锁,能保证线程安全。

关键代码片段

#include <iostream>
#include <mutex>
#include <atomic>

class ThreadSafeClass {
private:
    std::atomic<int> sharedData; // 使用原子类型来保证简单数据的线程安全
    std::mutex mtx; // 互斥锁,用于保护其他共享资源

public:
    ThreadSafeClass() : sharedData(0) {}

    // const成员函数,访问共享资源
    int getSharedData() const {
        // 如果共享资源不是原子类型,使用锁机制
        std::lock_guard<std::mutex> lock(mtx); 
        return sharedData.load();
    }

    // 非const成员函数,修改共享资源
    void incrementSharedData() {
        std::lock_guard<std::mutex> lock(mtx); 
        sharedData++;
    }
};

在上述代码中:

  • std::atomic<int> 保证了 sharedData 的原子操作,使其线程安全。
  • 对于更复杂的共享资源(若存在),使用 std::mutexstd::lock_guard 来确保在访问共享资源时的线程安全性。std::lock_guard 在构造时锁定互斥锁,在析构时解锁,从而保证了作用域内的线程安全。