如何在Haskell中编写Ctrl-C处理程序?

Rog*_*ach 18 haskell signals

我尝试了以下方法:

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

main :: IO ()
main = do
  installHandler keyboardSignal (Catch (do exitSuccess)) Nothing
  threadDelay (1000000000)
Run Code Online (Sandbox Code Playgroud)

但它只输出:

^CTest.hs: ExitSuccess
Run Code Online (Sandbox Code Playgroud)

Ctrl-C,而不是退出.我该怎么做呢?

Dan*_*her 20

来自以下文件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)
Run Code Online (Sandbox Code Playgroud)

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

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

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)
Run Code Online (Sandbox Code Playgroud)

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