You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 23:15:03