4

首先,拥有一个主线程(t2在我的情况下),开始和结束所有其他线程(t1)是标准的吗?

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?循环中,我是否应该有一个案例循环来不断测试哪个循环当前处于活动状态?

这种方法意味着整个程序是同时发生的,而不是按照其写入的顺序进行。这就是大型程序的实际工作方式吗?这是我应该给予反馈的方式吗?只在加入某个线程时告诉用户?

4

2 回答 2

1

thread1counter串行调用;所以他们一个接一个。

以下是修改后的代码。

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

更新

在原来的代码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
于 2013-10-13T10:08:31.990 回答
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
于 2013-10-13T10:19:47.677 回答