Ruby线程并发问题:使用Mutex仍得随机值,如何得到预期结果0?
问题解决:Ruby Mutex同步后结果随机的原因与修复
原代码问题分析
你的代码里Mutex的使用本身是正确的,但主线程没有等待所有子线程执行完毕就直接输出了shared_resource的值。当主线程执行到puts shared_resource时,大部分子线程可能还没来得及运行,所以结果是随机的。
修复后的代码
require 'thread' mutex = Mutex.new shared_resource = 0 threads = [] for i in 0..10000 threads << Thread.new do mutex.synchronize { shared_resource += 1 } end threads << Thread.new do mutex.synchronize { shared_resource -= 1 } end end threads.each(&:join) # 等待所有子线程执行完成 puts shared_resource
关键修复点
- 用数组
threads保存所有创建的线程对象 - 调用
threads.each(&:join)让主线程阻塞,直到所有子线程全部执行完毕,再输出结果
Ruby中Mutex与锁的正确用法
- Mutex的核心作用:保证同一时间只有一个线程能进入
synchronize块中的代码,避免多个线程同时修改共享资源导致的竞态条件。你原代码里的synchronize块用法是对的,shared_resource +=1和shared_resource -=1都被处理成了原子操作。 - 线程等待的必要性:当你创建子线程后,主线程不会自动等待子线程完成。如果主线程先结束,整个程序就会终止,未完成的子线程会被强制中断。所以必须用
Thread#join方法显式等待所有子线程执行完毕。 - 避免漏加锁:所有访问或修改共享资源的代码路径,都必须放在
mutex.synchronize块中,否则依然会出现竞态条件。
内容的提问来源于stack exchange,提问作者Santosh Mohanty
相关产品推荐
相关产品推荐

