2017-10-11 182 views
-2

我有一个类和属性有如何使用ruby线程在类中运行一个方法?

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} 

你有一些想法如何做到这一点的方法是什么?我看和prprmm比线程是不识别对象的实例的变量。

正确的答案应该是这个控制台

"person name 1" 
"person name 2" 
"person name ..." 
"person name etc" 
+0

你会得到什么?作为一个说明,多个线程同时写入控制台是一个很好的混合方式。一个线程应该处理输出。 – tadman

+0

感谢您的回答,我再次编辑,我需要通过控制台获取人名1,人名2,人名3。你可以帮我吗 ? –

+0

如果你需要这个顺序,线程会搞砸了。你为什么穿线?您需要以某种方式收集输出并在显示之前进行排序。 – tadman

回答

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|这样的东西。

相关问题