2013-10-13 37 views
4

首先,是否有一個主線程(在我的情況下爲t2),開始和結束所有其他線程(t1)的標準?如何使用Ruby線程

require 'curses' 
include Curses 

init_screen 

def counter(window_name, positionx, positiony, times_factor, sleep_factor) 
    window_name = Window.new(10,10,positionx,positiony) 
    window_name.box('|', '-') 
    window_name.setpos(2, 3) 
    window_name.addstr(window_name.inspect) 
    times_factor.times do |i| 
    window_name.setpos(1, 1) 
    window_name.addstr(i.to_s) 
    window_name.refresh 
    sleep sleep_factor 
    end 
end 
def thread1 
    counter("One",10,10,50,0.01) 
    counter("Two",20,20,200,0.01) 
    counter("Three",30,30,3,1.0) 
end 
def thread2 
    t1 = Thread.new{thread1()} 
    x = 4 
    chars = [" ","* ","** ","***","***","** ","* "," "] 
    four = Window.new(20,20,10,100) 
    four.box('|', '-') 
    four.setpos(1, 1) 
    i = 3 
    while t1.alive? 
    four.setpos(1, 1) 
    four.addstr chars[0] 
    four.addstr i.to_s 
    four.refresh 
    sleep 0.1 
    chars.push chars.shift 
    end 
    t1.join 
end 

t2 = Thread.new{thread2()} 
t2.join 

其次,我怎樣才能改變while t1.alive?循環,這樣,而不是t1操作過程中只是顯示一個明星動畫,我可以給什麼t1線程中實際發生的情況的反饋?例如,

counter1 has now finished 
counter2 has now finished 
counter3 has now finished 

要做到這一點,將每個櫃檯方法實際上必須要在內部t1自己的線程?在while t1.alive?循環中,我是否應該有一個能夠持續測試哪個循環當前還在運行的情況循環?

這種方法意味着整個程序正在發生,而不是按照其寫入的順序。這是大型程序實際工作的方式嗎?這是我應該如何提供反饋?只有在某個線程已加入時才告訴用戶?

回答

1

thread1連續調用counter;所以他們一個接一個地行動。

以下是修改後的代碼。

def thread1(count) 
    lock = Mutex.new 
    dec_count = proc { lock.synchronize { count[0] -= 1 } } 
    threads = [] 
    threads << Thread.new { counter("One",10,10,50,0.01); dec_count.call } 
    threads << Thread.new { counter("Two",20,20,200,0.01); dec_count.call } 
    threads << Thread.new { counter("Three",30,30,3,1.0); dec_count.call } 
    threads.each(&:join) 
end 

def thread2 
    active_count = [3] 
    t1 = Thread.new{thread1(active_count)} 
    chars = [" ","* ","** ","***","***","** ","* "," "] 
    four = Window.new(3,20,10,30) 
    four.box('|', '-') 
    four.setpos(1, 1) 
    while t1.alive? 
    four.setpos(1, 1) 
    four.addstr chars[0] 
    four.addstr active_count[0].to_s 
    four.refresh 
    sleep 0.1 
    chars.push chars.shift 
    end 
    t1.join 
end 

init_screen 
thread2 

UPDATE

在原始代碼window_name已被覆蓋。在下面,我替換了參數的名稱以防止出現這種情況。

def counter(thread_name, positiony, positionx, times_factor, sleep_factor) 
    window_name = Window.new(10, 10, positiony, positionx) 
    window_name.box('|', '-') 
    window_name.setpos(2, 3) 
    window_name.addstr(thread_name) 
    times_factor.times do |i| 
    window_name.setpos(1, 1) 
    window_name.addstr(i.to_s) 
    window_name.refresh 
    sleep sleep_factor 
    end 
end 
1

當你加入一個線程你實際上說,當Ruby解釋器等待這個線程完成運行,所以沒有反饋。你可以做的是在單獨的線程中運行每個計數器操作。這裏有個小例子,用它修改你的代碼

require "open-uri" 

th2 = Thread.new do 
    threads = ["first", "second", "third"].map do |i| 
    Thread.new do 
     open("http://stackoverflow.com/questions/19341175/how-to-thread-with-ruby") 
     Thread.current["status"] = "opened #{i} time" 
    end 
    end 
    threads.each { |th| th.join; puts th["status"] } 
end 

th2.join