MST

星途 面试题库

面试题:C++中成员函数访问对象数据在多线程下的线程安全基础问题

假设有一个C++类 `MyClass`,其中有一个成员变量 `int data;` 和一个成员函数 `void modifyData(int newVal)`,在多线程环境下,`modifyData` 函数直接执行 `data = newVal;` 操作,请问这样会有线程安全问题吗?如果有,如何解决?请简述原理并给出简单示例代码。
42.9万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 是否存在线程安全问题: 会有线程安全问题。当多个线程同时调用 modifyData 函数时,由于 data = newVal; 这一操作并非原子操作,可能会出现一个线程在读取 data 旧值后,还未完成赋值操作时,另一个线程也读取了 data 的旧值,从而导致最终 data 的值并非预期结果。

  2. 解决方法及原理: 可以使用互斥锁(std::mutex)来解决。互斥锁的原理是在同一时间只允许一个线程进入临界区(即 modifyData 函数中对 data 操作的部分),从而保证数据的一致性。当一个线程获取了互斥锁,其他线程就必须等待该线程释放互斥锁后才能获取并进入临界区。

  3. 示例代码

#include <iostream>
#include <mutex>

class MyClass {
private:
    int data;
    std::mutex mtx;

public:
    MyClass() : data(0) {}

    void modifyData(int newVal) {
        std::lock_guard<std::mutex> lock(mtx);
        data = newVal;
    }

    int getData() const {
        std::lock_guard<std::mutex> lock(mtx);
        return data;
    }
};

在上述代码中,modifyData 函数使用 std::lock_guard<std::mutex> 来自动管理互斥锁的加锁和解锁。当 lock_guard 对象创建时,会自动获取互斥锁 mtx,在函数结束时,lock_guard 对象析构,自动释放互斥锁。如果还需要读取 data 的值,在 getData 函数中同样使用 std::lock_guard<std::mutex> 来保证线程安全。