面试题答案
一键面试#include <iostream>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <chrono>
template <typename T>
class ThreadSafeQueue {
public:
ThreadSafeQueue(size_t capacity) : capacity_(capacity) {}
void enqueue(const T& item) {
std::unique_lock<std::mutex> lock(mutex_);
notFull_.wait(lock, [this] { return queue_.size() < capacity_; });
queue_.push(item);
lock.unlock();
notEmpty_.notify_one();
}
bool dequeue(T& item) {
std::unique_lock<std::mutex> lock(mutex_);
if (!notEmpty_.wait_for(lock, std::chrono::seconds(1), [this] { return!queue_.empty(); })) {
return false;
}
item = queue_.front();
queue_.pop();
lock.unlock();
notFull_.notify_one();
return true;
}
private:
std::queue<T> queue_;
std::mutex mutex_;
std::condition_variable notEmpty_;
std::condition_variable notFull_;
size_t capacity_;
};
你可以通过以下方式使用这个线程安全队列:
int main() {
ThreadSafeQueue<int> tsQueue(5);
std::thread producer([&tsQueue] {
for (int i = 0; i < 10; ++i) {
tsQueue.enqueue(i);
std::cout << "Produced: " << i << std::endl;
}
});
std::thread consumer([&tsQueue] {
int item;
while (true) {
if (tsQueue.dequeue(item)) {
std::cout << "Consumed: " << item << std::endl;
} else {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
});
producer.join();
consumer.join();
return 0;
}
在这个实现中:
ThreadSafeQueue
类使用std::mutex
来保护队列操作。std::condition_variable
notEmpty_
和notFull_
分别用于处理队列空和队列满的情况。enqueue
方法在队列满时等待notFull_
条件变量,直到队列有空间,然后将元素入队,并通知notEmpty_
。dequeue
方法在队列空时等待notEmpty_
条件变量,直到队列有元素,然后将元素出队,并通知notFull_
。同时,dequeue
方法使用wait_for
设置了等待超时,如果超时则返回false
。