C++ Windows多线程Event事件同步偶现卡死问题排查
问题原因分析
导致代码运行不稳定、卡死的核心原因有3个:
- 手动重置事件初始状态错误
你在main函数中创建完事件后直接调用了SetEvent(event),将事件初始置为有信号状态。这导致非最后线程第一次执行到WaitForSingleObject(event, INFINITE)时会直接返回,根本不会进入等待状态,直接进入下一轮for循环,多次累加runner的值,远大于你预期的data[0]-1,最后线程的while循环判断条件永远无法满足,直接卡死。 PulseEventAPI本身存在不可靠性
微软官方文档已经明确不推荐使用PulseEvent:该API仅能唤醒调用时刻已经进入等待状态的线程,如果此时有线程还没执行到WaitForSingleObject步骤,信号就会直接丢失,未等到信号的线程会永远卡在等待逻辑,导致程序死锁。- 多轮循环的同步逻辑缺失
代码外层有4次循环,你没有为每轮循环做事件状态、同步计数的对齐校验,上一轮循环的异常状态会直接传递到下一轮,进一步放大了前面两个问题的影响,比如会出现runner值累加到3的异常情况。
修复建议
- 删掉
main函数里的SetEvent(event)语句,事件初始状态应该为无信号。 - 废弃
PulseEvent,改用自动重置事件+主动计数校验的逻辑实现屏障同步,或者直接用Windows原生的同步屏障APIInitializeSynchronizationBarrier。 - 每轮循环结束后,统一在持有互斥锁的状态下重置
runner和事件状态,避免上一轮的异常值影响下一轮运行。
内容的提问来源于stack exchange,提问作者Ilya
相关产品推荐
相关产品推荐

