2017-10-11 180 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|這樣的東西。

相關問題