19

我尝试了以下方法:

import System.Exit
import System.Posix.Signals
import Control.Concurrent (threadDelay)

main :: IO ()
main = do
  installHandler keyboardSignal (Catch (do exitSuccess)) Nothing
  threadDelay (1000000000)

但它只输出:

^CTest.hs: ExitSuccess

on Ctrl-C,而不是退出。我应该如何正确地做到这一点?

4

1 回答 1

22

来自以下文档installHandler

安装了一个处理程序,它将在收到信号时(或不久之后)在新线程中调用操作。

exitWith:

注意:在 GHC 中,应该从主程序线程调用 exitWith 以退出进程。当从另一个线程调用时,exitWith 将照常抛出一个 ExitException,但该异常不会导致进程本身退出。

因此,exitSuccess处理程序不会结束该过程,这是预期的(尽管是意外的;)行为。

如果您想立即采取行动,

import System.Exit
import System.Posix.Signals
import Control.Concurrent

main :: IO ()
main = do
  tid <- myThreadId
  installHandler keyboardSignal (Catch (killThread tid)) Nothing
  threadDelay (1000000000)

收到信号后立即杀死线程。

不那么激烈,如果你想成功退出,那就是

import System.Exit
import System.Posix.Signals
import Control.Concurrent
import qualified Control.Exception as E

main :: IO ()
main = do
  tid <- myThreadId
  installHandler keyboardSignal (Catch (E.throwTo tid ExitSuccess)) Nothing
  threadDelay (10000000)

我认为它也可以可靠地工作,但我不完全确定。

于 2012-11-18T16:15:44.910 回答