退出函数为什么实际上没有终止程序

时间:2014-08-18 19:57:06

标签: ruby multithreading curses

为什么第二个线程实际上没有终止程序,应用程序仍在等待第一个线程的输入?

Curses.init_screen

first = Thread.new do
  loop {
    Curses.getch
  }
end

second = Thread.new do
  Curses.close_screen
  exit
end

second.join
first.join

操作系统 - Windows 8。

ruby​​ 2.0.0p481(2014-05-08)[x64-mingw32]

提前致谢。

3 个答案:

答案 0 :(得分:2)

我认为该范围内的exit正在运行Thread#exit而不是Kernel#exit(正如您所期望的那样)。但是,我使用的是Ruby 2.1.2,所以行为可能有点不同。

您可以通过运行代码来看到这一点:

2.1.0 :007 > Thread.new do
2.1.0 :008 >   puts self.inspect
2.1.0 :009?> end    

main => #<Thread:0x0000010142b8f8 sleep>

相反,如果您只是自己运行puts self.inspect(不在线程内):

2.1.0 :011 > puts self.inspect
main
 => nil

如果你明确地调用Kernel#exit

,你应该得到一个被杀死的进程
2.1.0 :001 > Thread.new do
2.1.0 :002 >   Kernel::exit
2.1.0 :003?> end

...在irb中,将关闭交互式会话(终止进程)。

一个简单的例子

如果我把它放在一个文件中:

# test.rb

first = Thread.new do
  while 4 != 5 do
    puts gets
  end
end

second = Thread.new do
  Kernel::exit
end

second.join
first.join

...并从我的命令行:

$ ruby test.rb

...程序会立即关闭,不会给我任何时间为first主题gets方法调用提供输入。

然而,如果我用Kernel::exit替换Thread::exit来电,程序将永远不会退出,但会不断提示我输入。

可能是2.0.0p4812.1.2 [x86_64]之间的差异?

答案 1 :(得分:1)

exit将终止当前正在运行的线程,在您的情况下为second。只有当前正在运行的线程是主线程时,它才会退出进程。

您可以阅读更多相关信息here

答案 2 :(得分:1)

看看the documentation for exit。它抛出SystemExit,所以你破坏了那个线程,但就是这样。