How to write Ctrl-C handler in Haskell?

杀马特。学长 韩版系。学妹 提交于 2019-12-04 16:03:26

问题


I tried the following approach:

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

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

But it only outputs:

^CTest.hs: ExitSuccess

on Ctrl-C, instead of exiting. How should I do it properly?


回答1:


From the docs of installHandler:

a handler is installed which will invoke action in a new thread when (or shortly after) the signal is received.

and exitWith:

Note: in GHC, exitWith should be called from the main program thread in order to exit the process. When called from another thread, exitWith will throw an ExitException as normal, but the exception will not cause the process itself to exit.

So an exitSuccess handler doesn't end the process, and that's expected (although unexpected ;) behaviour.

If you want immediate action,

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

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

kills the thread immediately upon receiving the signal.

Less drastic, if you want a successful exit, would be

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)

I think it will also work reliably, but I'm not entirely sure.



来源:https://stackoverflow.com/questions/13441676/how-to-write-ctrl-c-handler-in-haskell

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!