C语言多线程医院模拟项目Mutex锁失效导致挂号数小于0问题
问题原因分析
1. 封装后函数参数为值传递,未实际修改全局挂号容量
你拆分封装的wait_for_available_resource、release_resource函数中,资源计数参数是值传递,函数内修改的只是局部副本,完全不会作用到全局变量REGISTRATION_SIZE上:
wait_for_available_resource里的resource--仅修改局部入参,全局REGISTRATION_SIZE没有变更release_resource里的resource_number++同样仅修改局部入参,全局REGISTRATION_SIZE不会被增加
相当于你的容量计数逻辑完全失效,多线程可以无限制消耗挂号名额,自然会出现小于0的情况。
2. 锁和条件变量对象不匹配,未正确初始化
主函数初始化的是全局变量mutex和condRegister,但挂号逻辑中实际使用的是registration_mutex和register_cond,两个锁、两个条件变量完全是不同的对象:
- 你实际用的
registration_mutex没有经过pthread_mutex_init初始化,锁的行为完全未定义,根本起不到互斥作用 - 条件变量
register_cond也没有初始化,pthread_cond_wait和pthread_cond_signal逻辑完全失效,线程不会按预期等待/唤醒
3. 线程函数参数传递错误
thread_func中调用registration()时没有传入患者指针参数,而registration函数定义需要接收struct Patient *p,属于未定义行为,可能会导致内存访问异常、逻辑混乱。
4. 持有锁期间执行休眠,逻辑不合理
初始版本的registration函数中,在持有registration_mutex锁的情况下执行了sleepForMs休眠,这段时间你占用着锁,其他线程无法拿到锁修改REGISTRATION_SIZE、发送条件信号,会导致大量线程阻塞,条件等待逻辑效率极低。
修复建议
- 资源计数参数改为传指针,或者直接在函数内操作全局
REGISTRATION_SIZE变量,确保计数修改生效 - 统一锁和条件变量的命名,确保实际使用的对象就是主函数初始化的对象
- 修正
registration函数的传参问题 - 将持有锁期间的休眠逻辑移到锁外执行,避免占用锁阻塞其他线程
内容的提问来源于stack exchange,提问作者AssSoonAsPossiblee
相关产品推荐
相关产品推荐

