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

Ruby中如何使用条件变量按固定顺序执行线程并解决死锁问题

思路可行性与死锁原因

用条件变量控制执行顺序的思路是可行的,你遇到死锁的核心原因有两个:

  • 所有线程的逻辑仅能执行一次,执行完成后线程直接退出,没有实现重复执行n次的循环逻辑,主进程调用join时所有子线程已经终止,就会触发死锁报错。
  • 你把休眠逻辑放在了锁的临界区内,导致四个线程全程串行持有锁,完全没有释放锁的空隙,也不符合“计算完成后休眠”的需求。

修复实现方案

我们通过引入全局状态标记当前要执行的任务步骤、在每个线程内增加循环逻辑、将休眠移到临界区外解决问题,修复后代码如下:

a = 10
b = 2
n = 2
# 预先生成每个线程对应的随机休眠时长,单位可根据需求调整
sleep_times = Array.new(4) { rand(0.1..1.0) }

mutex = Mutex.new
cond = ConditionVariable.new
# current_step标记当前应执行的任务:0=求和、1=求差、2=求积、3=求商
current_step = 0

# 求和线程
t_sum = Thread.new do
  n.times do
    mutex.synchronize do
      # 非当前执行步骤则等待
      while current_step != 0
        cond.wait(mutex)
      end
      puts "SUM: #{a + b}"
      current_step = 1
      cond.broadcast
    end
    # 计算完成后再休眠,休眠逻辑放在锁外避免阻塞其他线程
    sleep sleep_times[0]
  end
end

# 求差线程
t_diff = Thread.new do
  n.times do
    mutex.synchronize do
      while current_step != 1
        cond.wait(mutex)
      end
      puts "DIFFERENCE: #{a - b}"
      current_step = 2
      cond.broadcast
    end
    sleep sleep_times[1]
  end
end

# 求积线程
t_product = Thread.new do
  n.times do
    mutex.synchronize do
      while current_step != 2
        cond.wait(mutex)
      end
      puts "PRODUCT: #{a * b}"
      current_step = 3
      cond.broadcast
    end
    sleep sleep_times[2]
  end
end

# 求商线程
t_div = Thread.new do
  n.times do |round_idx|
    mutex.synchronize do
      while current_step != 3
        cond.wait(mutex)
      end
      puts "DIVISION: #{a / b}"
      # 非最后一轮输出空行分隔
      puts "" if round_idx != n - 1
      current_step = 0
      cond.broadcast
    end
    sleep sleep_times[3]
  end
end

# 等待所有线程执行完成
t_sum.join
t_diff.join
t_product.join
t_div.join

运行上述代码即可输出和示例完全一致的结果,且符合仅创建一次线程、不使用队列的限制要求。

优化建议

  • 可将四个线程的公共调度逻辑抽离,用数组存储对应的计算函数,减少重复代码,方便后续扩展其他计算逻辑。
  • 商的计算逻辑可增加除数为0的异常处理,避免b为0时程序崩溃。

内容的提问来源于stack exchange,提问作者KleberPF

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 05:36:06