为什么这个红宝石线程片不起作用?

时间:2015-12-14 18:40:34

标签: ruby multithreading

我有一个具有@my_threads数组属性的Ruby类。我这样做(伪代码)

class MyClass
  @my_threads = []
  ...
  def do_something()
    %w[host1 host2].each do |h|
      cmd = %Q{ssh to $h; do_something; exit}
      t = Thread.new(cmd)
      @my_threads << t
    end
    @my_threads.each {|t| t.join}
  end

  def do_something_else()
    @my_threads.clear
    %w[host1 host2].each do |h|
      cmd = %Q{ssh to $h; do_something_else; exit}
      t = Thread.new(cmd)
      @my_threads << t
    end
    @my_threads.each {|t| t.join}
  end
end

myClass = MyClass.new
myClass.do_something
myClass.do_something_else

do_something按预期运行,也就是说,我生成两个线程,一个用于host1,另一个用于host2,它们分别为每个主机ssh并执行某些操作然后退出。

Howerver,当do_something_else执行时,它确实产生了两个线程,但是对于host2,也就是在我的控制台输出上,我看到脚本ssh&to to to host2两次。我做的a put cmd并看到cmd是正确的,也就是第一个用于host1而下一个用于host2。

有什么建议吗?谢谢!

1 个答案:

答案 0 :(得分:0)

我得到了一些工作,也就是说,如下所示进行睡眠呼叫。但我不明白为什么?从cmd变量更新到创建线程之间,它必须是竞争条件。有更好的解决方案吗?

class MyClass
  @my_threads = []
  ...
  def do_something()
    %w[host1 host2].each do |h|
      cmd = %Q{ssh to $h; do_something; exit}
      t = Thread.new(cmd)
      @my_threads << t
    end
    @my_threads.each {|t| t.join}
  end

  def do_something_else()
    @my_threads.clear
    %w[host1 host2].each do |h|
      cmd = %Q{ssh to $h; do_something_else; exit}
      t = Thread.new(cmd)
      @my_threads << t
      ######### Added sleep call ###########
      sleep 5 
    end
    @my_threads.each {|t| t.join}
  end
end

myClass = MyClass.new
myClass.do_something
myClass.do_something_else