恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
计算机操作系统17
首页
资讯中心
/
计算机操作系统17
计算机操作系统17
发布时间:2026/8/6 10:20:42
第十七课生产者-消费者问题Producer-Consumer Problem一、什么是生产者-消费者先来看一个生活例子。假设有一家奶茶店。员工负责做奶茶。顾客负责拿奶茶。中间有一个奶茶架。员工生产者 ↓ 【奶茶架】 ↓ 顾客消费者员工一直做奶茶。顾客一直拿奶茶。是不是很合理二、为什么会出问题假设奶茶架只能放3 杯奶茶。开始[ ][ ][ ]员工一直做。[奶][ ][ ]继续[奶][奶][ ]继续[奶][奶][奶]已经满了。如果员工还继续放。是不是放不下所以必须等待。另一边。如果奶茶架空了。[ ][ ][ ]顾客还来拿。是不是拿不到所以消费者也必须等待。三、操作系统里的对应关系奶茶店对应程序。奶茶店操作系统员工生产者线程顾客消费者线程奶茶架缓冲区Buffer奶茶数据缓冲区就是一块共享内存。四、缓冲区会出现两个问题假设缓冲区大小3现在已经满了。生产者还能放吗不能。必须等待。另一种。缓冲区为空。消费者还能取吗不能。必须等待。所以这里需要同步。另外。如果两个生产者同时往同一个位置写数据。是不是又会覆盖两个消费者同时取同一个数据。是不是又会重复所以还需要互斥。一个总结生产者-消费者问题里同时存在两类需求同步控制什么时候能生产、什么时候能消费。互斥保证同一时刻只有一个线程修改缓冲区。很多初学者只想到同步忘了互斥这是最容易丢分的地方。五、需要几个信号量这是考试第一问。答案三个。① mutex作用保护缓冲区。初值1因为一次只能一个线程操作。② empty表示空位置。例如缓冲区大小5。开始empty 5说明还有5 个位置。③ full表示已有数据。开始full 0因为一开始没有任何数据。六、三个信号量总结信号量初值含义mutex1互斥访问缓冲区emptyn缓冲区大小空缓冲区数量full0已放入数据数量这是考试必背。七、生产者应该怎么写假设生产一个数据。第一步是不是先看有没有空位置所以第一句P(empty);意思申请一个空位置。第二步。是不是还要锁门因为别人不能同时改缓冲区。于是P(mutex);第三步。真正放数据。put();第四步。放完。是不是解锁V(mutex);第五步。缓冲区多了一个数据。消费者可以拿了。于是V(full);完整代码P(empty);P(mutex);放入数据;V(mutex);V(full);八、消费者怎么写第一步。有没有数据所以先P(full);没有数据就等待。第二步。锁门。P(mutex);第三步。真正拿数据。get();第四步。解锁。V(mutex);第五步。空位置多了一个。于是V(empty);完整P(full);P(mutex);取数据;V(mutex);V(empty);九、为什么顺序不能写反来看一个经典错误。有人写P(mutex);P(empty);这样可以吗不可以。为什么假设缓冲区已经满了。生产者执行P(mutex)拿到了锁。接着执行P(empty)发现没有空位。于是睡觉。注意它睡觉的时候还拿着锁。消费者想拿数据。第一句P(full)成功。第二句P(mutex)发现锁没了。消费者也睡觉。结果生产者 等消费者 ↓ 消费者 等生产者是不是谁也醒不过来这就是死锁Deadlock十、为什么正确顺序不会死锁正确一定先P(empty)资源够。再P(mutex)所以不会拿着锁睡觉。这一点考试经常考。十一、一张图理解生产者 P(empty) P(mutex) 放入数据 V(mutex) V(full) ----------------------- 消费者 P(full) P(mutex) 取出数据 V(mutex) V(empty)建议你把这张图手写一遍记忆效果最好。十二、考试最喜欢问的问题问为什么需要三个信号量答案信号量作用empty保证不会放满full保证不会取空mutex保证互斥问为什么mutex初值1因为一次一个线程。问为什么full初值0因为开始没有数据。问为什么empty初值n因为开始全部都是空位。十三、口诀★★★★★考试前一定背。生产者P(empty) ↓ P(mutex) ↓ 生产 ↓ V(mutex) ↓ V(full)消费者P(full) ↓ P(mutex) ↓ 消费 ↓ V(mutex) ↓ V(empty)口诀生产先空后锁消费先满后锁解锁之后再通知。这句话能帮助你记住正确的 P/V 操作顺序。十四、本课重点★★★★★必须掌握✅ 三个信号量mutex 1empty nfull 0✅ 生产者P(empty);P(mutex);生产;V(mutex);V(full);✅ 消费者P(full);P(mutex);消费;V(mutex);V(empty);✅资源信号量empty/full要先申请再申请互斥锁释放时先释放互斥锁再通知资源变化。