面试题答案
一键面试#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
std::queue<int> dataQueue;
std::mutex queueMutex;
std::condition_variable dataAvailable;
bool finished = false;
void producer() {
for (int i = 0; i < 10; ++i) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::unique_lock<std::mutex> lock(queueMutex);
dataQueue.push(i);
std::cout << "Produced: " << i << std::endl;
lock.unlock();
dataAvailable.notify_one();
}
std::unique_lock<std::mutex> lock(queueMutex);
finished = true;
lock.unlock();
dataAvailable.notify_all();
}
void consumer() {
while (true) {
std::unique_lock<std::mutex> lock(queueMutex);
dataAvailable.wait(lock, [] { return!dataQueue.empty() || finished; });
if (dataQueue.empty() && finished) {
break;
}
int data = dataQueue.front();
dataQueue.pop();
std::cout << "Consumed: " << data << std::endl;
lock.unlock();
}
}
条件变量的作用及使用原因
- 作用:条件变量
dataAvailable
用于线程间的同步。生产者线程在向队列中添加数据后,通过dataAvailable.notify_one()
或dataAvailable.notify_all()
通知等待在条件变量上的消费者线程,队列中有新数据可以处理了。消费者线程在从队列取数据前,通过dataAvailable.wait(lock, [] { return!dataQueue.empty() || finished; })
等待条件变量被通知,并且在被唤醒后检查队列是否有数据(或是否生产者已完成生产),避免虚假唤醒。 - 使用原因:如果不使用条件变量,消费者线程需要不断地轮询队列是否有数据,这会浪费大量CPU资源。条件变量提供了一种线程等待特定条件满足的机制,线程在等待时会被阻塞挂起,不占用CPU资源,直到条件变量被通知,这样可以显著提高程序的效率,同时保证线程间的正确同步。
你可以通过以下方式测试这两个函数:
int main() {
std::thread producerThread(producer);
std::thread consumerThread(consumer);
producerThread.join();
consumerThread.join();
return 0;
}