如何与Ruby进行交互

时间:2013-10-13 02:20:24

标签: ruby multithreading

首先,在我的情况下有一个主线程(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?循环中,我是否应该有一个不断测试哪个循环当前存活的case循环?

这种方法意味着整个程序会立即发生,而不是遵循其编写的顺序。这是更大的程序实际工作的吗?这是我应该如何提供反馈?只告诉用户某个线程何时加入?

2 个答案:

答案 0 :(得分: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

<强>更新

原始代码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 :(得分: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