C++多线程实现理发师问题条件变量阻塞故障排查
你代码里的主要错误分为语法错误和逻辑错误两类:
1. 致命语法错误:理发师对象未正确实例化
main函数里的Barber dan(); 触发了C++的「最令人头疼的解析」规则:这行代码不会被解析为创建Barber类的对象dan,而是被解析为声明一个返回值为Barber类型、无入参的函数dan。所以你的理发师线程从始至终都没有被创建启动,自然不会有任何执行逻辑。
修正方案:改成Barber dan(mybarbershop); 即可。
2. 理发师逻辑缺少循环
当前Barber::work函数只会执行一次,执行完成后线程直接退出,不符合理发师循环接待顾客的业务逻辑,需要在外层加死循环(如果需要退出机制可以额外加终止标记)。
3. 条件变量使用不符合规范
- 等待同一条件变量的所有线程,必须绑定同一个互斥锁来保护共享状态。你当前理发师等待
cv时用的是自己的私有锁b_mu,每个顾客等待cv时用的是自己的私有锁c_mu,完全违反了条件变量的使用规则,会导致通知丢失、虚假唤醒无法正确处理等问题。 - 建议新增一个全局的互斥锁专门保护
num_waiting和条件变量的操作,替换现在每个类私有的锁。
4. 业务逻辑错误
- 顾客进店后先增加
num_waiting再等待,理发师唤醒顾客后、开始理发前就应该减少num_waiting(因为顾客已经离开等候椅坐到理发椅了),而不是理完发再减。 - 单个条件变量同时管理理发师休眠和多个顾客等待的逻辑容易混乱,建议拆分两个条件变量:一个用于通知理发师有顾客到店,一个用于通知顾客可以理发。
5. 其他小问题
main函数中customers.reserve(NUM_CUSTOMERS-1);逻辑冗余,当NUM_CUSTOMERS=1时预留0个空间,没有实际意义,直接删除即可,或者改为reserve(NUM_CUSTOMERS)。
内容的提问来源于stack exchange,提问作者Shizo
相关产品推荐
相关产品推荐

