MST

星途 面试题库

面试题:C++ 中如何使用互斥锁解决对象间数据共享的并发问题

在 C++ 多线程编程场景下,假设有两个线程需要访问和修改同一个对象中的共享数据成员。请用代码示例展示如何使用 `std::mutex` 来保护该共享数据,以避免数据竞争。并简要解释 `std::mutex` 的工作原理。
16.1万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

代码示例

#include <iostream>
#include <thread>
#include <mutex>

class SharedData {
public:
    int data;
    std::mutex mtx;

    SharedData() : data(0) {}

    void increment() {
        std::lock_guard<std::mutex> lock(mtx);
        ++data;
    }

    void decrement() {
        std::lock_guard<std::mutex> lock(mtx);
        --data;
    }

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

void threadFunction1(SharedData& sharedData) {
    for (int i = 0; i < 1000; ++i) {
        sharedData.increment();
    }
}

void threadFunction2(SharedData& sharedData) {
    for (int i = 0; i < 1000; ++i) {
        sharedData.decrement();
    }
}

int main() {
    SharedData sharedData;
    std::thread thread1(threadFunction1, std::ref(sharedData));
    std::thread thread2(threadFunction2, std::ref(sharedData));

    thread1.join();
    thread2.join();

    std::cout << "Final value: " << sharedData.getValue() << std::endl;
    return 0;
}

std::mutex 工作原理

std::mutex 是 C++ 标准库提供的互斥锁。其工作原理基于操作系统的同步原语。当一个线程调用 lock 方法时,如果互斥锁处于未锁定状态,该线程会锁定互斥锁并继续执行;如果互斥锁已被其他线程锁定,调用 lock 的线程会被阻塞,直到互斥锁被解锁。unlock 方法用于释放互斥锁,使得其他被阻塞的线程有机会竞争并锁定该互斥锁。std::lock_guard 是一个 RAII(Resource Acquisition Is Initialization) 类型,在构造时自动调用 lock,在析构时自动调用 unlock,从而简化了锁的管理,确保在作用域结束时锁一定会被释放,避免了手动管理锁可能导致的忘记解锁等问题。