MST

星途 面试题库

面试题:C++ 堆栈在多线程环境下的安全实现

在多线程环境中,如何保证C++ 实现的堆栈的线程安全性?请说明具体的同步机制,并修改之前实现的堆栈类以适应多线程环境,给出关键代码片段及说明。
18.7万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

同步机制

在多线程环境中保证C++ 实现的堆栈的线程安全性,可以使用以下常见同步机制:

  1. 互斥锁(Mutex)std::mutex是C++标准库提供的互斥锁,通过锁定和解锁操作来保护共享资源(如堆栈),同一时间只有一个线程可以获得锁并访问堆栈。
  2. 读写锁(Read - Write Lock):如果读操作远多于写操作,可以使用读写锁(如std::shared_mutex)。读操作可以同时进行,写操作则需要独占访问,以保证数据一致性。
  3. 条件变量(Condition Variable)std::condition_variable结合互斥锁使用,用于线程间的同步。例如,当堆栈为空时,从堆栈弹出元素的线程可以等待条件变量,直到有元素被压入堆栈。

修改堆栈类以适应多线程环境

以下以使用std::mutexstd::condition_variable为例,给出关键代码片段及说明:

#include <iostream>
#include <stack>
#include <mutex>
#include <condition_variable>
#include <thread>

class ThreadSafeStack {
public:
    void push(int value) {
        std::unique_lock<std::mutex> lock(mutex_);
        stack_.push(value);
        lock.unlock();
        cond_.notify_one(); // 通知等待的线程,堆栈有新元素
    }

    bool pop(int& value) {
        std::unique_lock<std::mutex> lock(mutex_);
        // 等待直到堆栈不为空
        cond_.wait(lock, [this] { return!stack_.empty(); });
        if (stack_.empty()) {
            return false;
        }
        value = stack_.top();
        stack_.pop();
        return true;
    }

private:
    std::stack<int> stack_;
    std::mutex mutex_;
    std::condition_variable cond_;
};

代码说明

  1. 成员变量
    • stack_是实际存储数据的堆栈。
    • mutex_用于保护对stack_的访问。
    • cond_用于线程间的同步,通知等待的线程堆栈状态的变化。
  2. push函数
    • 使用std::unique_lock<std::mutex>来锁定mutex_,确保对stack_push操作是线程安全的。
    • 操作完成后解锁互斥锁,并调用cond_.notify_one()通知一个等待在条件变量上的线程(如果有),堆栈中有新元素。
  3. pop函数
    • 使用std::unique_lock<std::mutex>锁定mutex_
    • 使用cond_.wait等待条件变量,直到stack_不为空。cond_.wait接受一个谓词(这里是[this] { return!stack_.empty(); }),只有当谓词为真时,wait才会返回。
    • 检查stack_是否为空(防止虚假唤醒),如果不为空则弹出元素并返回true,否则返回false