系列综述:
来源:该系列是主要参考《大话设计模式》和《设计模式(可复用面向对象软件的基础)》,其他详细知识点拷验来自于各大平台大佬的博客。
总结:设计模式汇总篇
如果对你有用,希望关注·点赞·收藏一波。
文章目录
- 生产者消费者模型
- 参考博客
😊点此到文末惊喜↩︎
生产者消费者模型
- 定义
- 目的:多线程环境中,解决
生产者
和消费者
对共享队列
访问的同步
问题(共享和互斥、同步和异步概念)
- 目的:多线程环境中,解决
- 过程
- 生产者:生成数据并放入共享队列(缓冲区)中
- 消费者:从共享队列(缓冲区)中获取数据并进行消费
- 共享队列的同步:使用PV信号量匹配生产者和消费者的速率差异
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
using namespace std;
// 定义消息队列类
class MessageQueue {
public:
MessageQueue () {}
// 生产者生产数据放入消息队列中
void push(string msg) {
unique_lock<mutex> lock(m_mutex); // 1.上锁:保证{}范围内的互斥访问
m_queue.push(msg); // 2.生产:向消息队列中添加消息
m_cv.notify_one(); // 3.唤醒:唤醒在该条件变量上等待队列优先级最高的一个线程
// m_cv.notify_all()会唤醒所有线程,但是会造成资源争用,要谨慎使用
}
// 消费者从消息队列中取出消息
std::string pop() {
std::unique_lock<std::mutex> lock(m_mutex);// 1. 上锁
// 2. 队列为空则等待:如果队列为空,等待生产者添加消息
while (m_queue.empty()) {
m_cv.wait(lock); // 使当前线程在条件变量上等待
}
// 3. 消费:取出消息并返回
string msg = m_queue.front();
m_queue.pop();
return msg;
}
private:
mutex m_mutex; // 互斥锁:保证消息队列和条件变量的互斥访问
condition_variable m_cv; // 条件变量:保证生产者和消费者的同步
queue<std::string> m_queue; // 消息队列:生产者和消费者的缓冲区
};
// 定义生产者线程函数
void producer(MessageQueue& mq) {
for (int i = 0; i < 10; ++i) {
std::string msg = "message " + std::to_string(i);
mq.push(msg);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
// 生产者线程休眠一段时间
}
}
// 定义消费者线程函数
void consumer(int id, MessageQueue& mq) {
for (int i = 0; i < 5; ++i) {
string msg = mq.pop();
cout << "consumer " << id << " get message: " << msg << std::endl;
this_thread::sleep_for(std::chrono::milliseconds(200));
// 消费者线程休眠一段时间
}
}
// 测试生产者消费者模型
int main() {
MessageQueue mq;
std::thread t1(producer, std::ref(mq));
std::thread t2(consumer, 1, std::ref(mq));
std::thread t3(consumer, 2, std::ref(mq));
std::thread t4(consumer, 3, std::ref(mq));
t1.join();
t2.join();
t3.join();
t4.join();
return 0;
}
🚩点此跳转到首行↩︎
参考博客
- 适配器模式
- 设计模式(四)——搞懂什么是代理模式
- 适配器模式
- c++设计模式:代理模式
- 代理模式
- 待定引用
- 待定引用
- 待定引用