即使 $Deppial.Cuin < /Cuff>使整个部署线程执行,它阻止读取任何输入,因此我不能在执行中间重置它。我不能在脚本结尾加入它,ruby,multithreading,asynchronous,Ruby,Multithreading,Asynchronous" /> 即使 $Deppial.Cuin < /Cuff>使整个部署线程执行,它阻止读取任何输入,因此我不能在执行中间重置它。我不能在脚本结尾加入它,ruby,multithreading,asynchronous,Ruby,Multithreading,Asynchronous" />

Ruby 如何创建一个可重置的;过程“;或;“线程”;用红宝石? 我有这个脚本,上传一些文件,通过SSH连接,在远程服务器上做一些东西,有点像部署脚本,我想让它在我想要的时候运行,并且能够在处理过程中重置它。 def deploy # some stuff happens here end def do_deploy $deploy.kill! if $deploy $deploy = Thread.new { deploy } $deploy.join # when I don't have the join here, it stop executing the deploy # like after first when thread switches to something else, and # then never finishes end reading = Thread.new do while line = gets.chomp! case line when "q" then puts "exiting" Thread.exit exit when "r" then do_deploy end end end reading.join >即使 $Deppial.Cuin < /Cuff>使整个部署线程执行,它阻止读取任何输入,因此我不能在执行中间重置它。我不能在脚本结尾加入它

Ruby 如何创建一个可重置的;过程“;或;“线程”;用红宝石? 我有这个脚本,上传一些文件,通过SSH连接,在远程服务器上做一些东西,有点像部署脚本,我想让它在我想要的时候运行,并且能够在处理过程中重置它。 def deploy # some stuff happens here end def do_deploy $deploy.kill! if $deploy $deploy = Thread.new { deploy } $deploy.join # when I don't have the join here, it stop executing the deploy # like after first when thread switches to something else, and # then never finishes end reading = Thread.new do while line = gets.chomp! case line when "q" then puts "exiting" Thread.exit exit when "r" then do_deploy end end end reading.join >即使 $Deppial.Cuin < /Cuff>使整个部署线程执行,它阻止读取任何输入,因此我不能在执行中间重置它。我不能在脚本结尾加入它,ruby,multithreading,asynchronous,Ruby,Multithreading,Asynchronous,我基本上需要做的是,在侦听输入的同时运行任务,并能够在任何给定时间终止进程并重新启动它。或者更好的方法是,向它发送一条可以立即得到处理的消息,比如关闭测试执行 我知道杀死线程并不是一件好事,但在这种情况下,我不认为这是一个大问题 我还想指出,我正在Windows上工作,所以我没有可用的fork() 没有线程的情况下,还有其他方法解决这个问题吗 编辑:刚刚发现,调用会阻止所有其他线程执行,直到给出任何输入。在这个例子中 t1 = Thread.new { 10.times { |i| puts i

我基本上需要做的是,在侦听输入的同时运行任务,并能够在任何给定时间终止进程并重新启动它。或者更好的方法是,向它发送一条可以立即得到处理的消息,比如关闭测试执行

我知道杀死线程并不是一件好事,但在这种情况下,我不认为这是一个大问题

我还想指出,我正在Windows上工作,所以我没有可用的
fork()

没有线程的情况下,还有其他方法解决这个问题吗

编辑:刚刚发现,调用
会阻止所有其他线程执行,直到给出任何输入。在这个例子中

t1 = Thread.new { 10.times { |i| puts i } }
t2 = Thread.new { puts gets }
t1.join
t2.join
直到我给
get
提供一些输入,t1才会执行。它只是永远坐在那里。如何在不阻塞所有线程的情况下读取输入

编辑2:刚刚发现,这是一个


edit3:在JRuby或Ruby 1.9中,这个问题消失了。使用JRuby。它有真正的线程,并且不受C Ruby解释器拥有的GIL(全局解释器锁)的约束


使用
线程.join
时,调用线程将阻塞,直到指定的线程终止。这就是您此时无法处理输入的原因(
do\u deploy
不再执行)

调用
thread.new
时,应立即执行
deploy
线程。如果我正确读取了您的代码,您希望将调用从
do_deploy
内部移动到
reading
块中的
.join
。试着在
阅读
块中使用以下内容(我前面没有Ruby,因此这可能不是完美的语法):

当输入“r”时,应启动(或终止并重新启动)部署进程,然后返回到输入处理循环。输入一个“q”,则
deploy
进程将被发送一个“terminate”信号,输入处理循环将等待它终止,然后自行终止


使用Ruby线程时,当
deploy
线程工作时,您可能会遇到输入处理线程似乎没有运行的问题(繁忙线程可能会耗尽低优先级线程)。如果发生这种情况,我建议在
deploy
例程中添加一些显式调用到
Thread.pass
。这将强制线程调度程序让另一个线程运行。您可能还想尝试使用线程优先级,并将输入处理线程置于比工作线程更高的优先级。

FYI,
thread.fork
只是
thread.new的别名,即使在Windows上也应该可用。Ruby在其自己的进程内处理线程,因此底层操作系统不应碍事。我不是说Thread.fork,而是说Kernel.fork,它创建了一个子进程。我刚刚发现问题在于
gets
,它阻止了所有其他线程,请检查editgets不应在1.9/jruby中阻止
reading = Thread.new do
  while line = gets.chomp!
    case line
    when "q" then
      puts "exiting"
      $deploy.kill if $deploy
      break
    when "r" then
      do_deploy
    end
  end
  $deploy.join
end