如何使用ruby中的线程在类中运行方法?

时间:2017-10-11 22:24:28

标签: ruby-on-rails ruby multithreading rubygems

我有一个班级和属性

class Person
  attr_accessor :name
  def say_hello
   puts "person name #{self.name} "
  end
end

现在我想执行方法say_hello但是使用这个帖子

queue_thread= []
1..100.times do |number|
  person= Person.new
  person.name= number.to_s
   thread_to_run=Thread.new {person.say_hello}
   queue_thread << thread_to_run
end
queue_thread.map {|thread_current| thread_current.join}

你有什么想法吗?我看了,而且这个问题比线程不是通过对象实例识别vars。

答案正确应该在控制台中

"person name 1"
"person name 2"
"person name ..."
"person name etc"

1 个答案:

答案 0 :(得分:0)

此代码的问题在于它在调用join之前触发多个线程 - 此时,由于线程的异步性质,某些线程可能以不正确的顺序被调用。

一旦调用线程,一个选项就是join。这实际上会暂停迭代直到线程完成,因此您知道它们将保持有序:

100.times do |number|
  person= Person.new
  person.name= number.to_s
  Thread.new {person.say_hello}.join
end

请注意,此处使用线程确实没有意义,但它至少会显示join可以正常工作。

另一个选项(也不必要地使用线程)通过将它存储为lambda来延迟线程调用。这基本上是相同的,但允许您将其拆分为两个迭代:

queue_threads= []
1..100.times do |number|
  person= Person.new
  person.name= number.to_s
  thread_lambda = -> { Thread.new {person.say_hello} }
  queue_threads.push(thread_lambda)
end
queue_threads.map {|thread_lambda| thread_lambda.call.join}

另请注意,1..100.times并未按照您的想法行事。这与说100.times是一回事,因此,例如,如果你说99..100.times,99将被忽略,它将是100次迭代而不仅仅是1.如果你想迭代一个范围,你可以使用类似99..100.each do |i|的东西。