使用mutex实现原子计数,计数正确但打印无序的原因咨询
为什么互斥锁保证了计数正确,但打印顺序依然混乱?
嗨,这个问题其实是对互斥锁作用范围的典型误解,咱们一步步拆解来看:
互斥锁到底保护了什么?
你的代码里,acquire(&lock)和release(&lock)包裹的是对共享文件count.txt的读写操作(ADD1和Load),这部分确实被互斥锁牢牢保护了:
- 同一时间只有一个线程能修改或读取
count.txt - 不会出现两个线程同时写导致的计数丢失,所以最终总数能到2000是完全符合预期的
打印顺序混乱的核心原因
问题出在**printf操作是在释放锁之后执行的**!
举个具体的执行流程例子:
- 线程A获取锁,把count从5加到6,Load得到6,然后释放锁
- 线程B立刻抢到锁,把count从6加到7,Load得到7,然后释放锁
- 这时候线程B的
printf先被操作系统调度执行,打印出7;紧接着线程A的printf才执行,打印出6 - 最终输出就会出现
7在6前面的混乱情况
简单说:互斥锁只保证了「计数操作的原子性」,但没保证「计数后的打印操作和计数操作绑定成一个原子单元」——释放锁后,线程的执行顺序就交给操作系统的调度器了,谁先抢到CPU时间片谁就先打印。
怎么修复打印顺序?
如果想要打印的序列严格从1到2000递增,只需要把printf也放到互斥锁的保护范围内,让「计数+打印」变成一个不可拆分的原子操作:
for(int i=0; i<1000;i++){ acquire(&lock); ADD1("count.txt"); temp=Load("count.txt"); printf("\n %d",temp); // 把printf移到锁内 release(&lock); }
这样一来,每个线程必须完成计数、打印后才会释放锁,下一个线程才能开始操作,自然就能保证打印顺序和计数顺序完全一致了。
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

