面试题答案
一键面试同步机制
在多线程环境中保证C++ 实现的堆栈的线程安全性,可以使用以下常见同步机制:
- 互斥锁(Mutex):
std::mutex
是C++标准库提供的互斥锁,通过锁定和解锁操作来保护共享资源(如堆栈),同一时间只有一个线程可以获得锁并访问堆栈。 - 读写锁(Read - Write Lock):如果读操作远多于写操作,可以使用读写锁(如
std::shared_mutex
)。读操作可以同时进行,写操作则需要独占访问,以保证数据一致性。 - 条件变量(Condition Variable):
std::condition_variable
结合互斥锁使用,用于线程间的同步。例如,当堆栈为空时,从堆栈弹出元素的线程可以等待条件变量,直到有元素被压入堆栈。
修改堆栈类以适应多线程环境
以下以使用std::mutex
和std::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_;
};
代码说明:
- 成员变量:
stack_
是实际存储数据的堆栈。mutex_
用于保护对stack_
的访问。cond_
用于线程间的同步,通知等待的线程堆栈状态的变化。
push
函数:- 使用
std::unique_lock<std::mutex>
来锁定mutex_
,确保对stack_
的push
操作是线程安全的。 - 操作完成后解锁互斥锁,并调用
cond_.notify_one()
通知一个等待在条件变量上的线程(如果有),堆栈中有新元素。
- 使用
pop
函数:- 使用
std::unique_lock<std::mutex>
锁定mutex_
。 - 使用
cond_.wait
等待条件变量,直到stack_
不为空。cond_.wait
接受一个谓词(这里是[this] { return!stack_.empty(); }
),只有当谓词为真时,wait
才会返回。 - 检查
stack_
是否为空(防止虚假唤醒),如果不为空则弹出元素并返回true
,否则返回false
。
- 使用