Ruby 2.5.1线程输出与《扎实的Ruby程序员》示例不符的咨询
关于Ruby线程执行顺序与主线程终止的问题
问题1:未使用join时仅输出Outside the thread
你遇到的第一个情况核心原因是主线程的生命周期直接决定子线程的存活状态。当你启动子线程后,主线程没有等待子线程完成,而是继续执行puts "Outside the thread",之后主线程就直接结束了。在Ruby程序中,只要主线程退出,所有正在运行的子线程会被立即终止——你的子线程根本没来得及执行puts "Starting the thread"就被干掉了。
作者的输出能看到Starting the thread,只是因为他的环境里主线程执行到puts "Outside the thread"的速度比子线程启动慢了一点点,子线程抢到了执行时间片。但这种情况是完全不确定的,线程调度由操作系统全权决定,绝对不能依赖这种偶然的顺序。
问题2:使用join后输出顺序与作者不同
当你把线程赋值给t并调用t.join时,主线程会等待这个子线程执行完毕再退出,所以三个输出都会出现,但顺序依然没有固定保证:
- 你的输出是
Outside the thread先出现,说明主线程在子线程启动前就抢到了执行时间片,先执行了这个puts - 作者的输出是
Starting the thread先出现,说明他的环境中子线程先被调度执行
这是正常现象,Ruby 2.5.1使用的是内核级线程(Native Threads),线程的执行顺序由操作系统调度器决定,没有任何规则能强制固定顺序,所以两种输出都是合理的,你并没有遗漏任何配置或代码。
验证与总结
如果你只是想调试时让子线程先执行,可以在主线程的puts前加一段短暂的sleep(但这仅适合调试,生产环境不要依赖);如果是业务逻辑需要固定执行顺序,应该用同步机制(比如Mutex)来控制。但本质上,多线程编程的核心特点之一就是执行顺序的不可预测性,这是你需要适应的常态。
比如多次运行下面的代码,你可能会看到两种不同的输出顺序,这都是正常的:
t = Thread.new do puts "Starting the thread" sleep 1 puts "At the end of the thread" end puts "Outside the thread" t.join
内容的提问来源于stack exchange,提问作者Mike Glaz
相关产品推荐
相关产品推荐

