2012-11-18 42 views
18

我尝试以下方法:如何在Haskell中编写Ctrl-C处理程序?

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 

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

回答

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) 

在接到信号,立即杀死线程。

那么激烈,如果你想要一个成功的退出,将

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) 

我认为它会可靠地工作,但我不能完全肯定。

+0

线程'threadDelay(10000000)'做了什么? – Langston

+1

['threadDelay'](http://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Concurrent.html#v:threadDelay)“暂停当前线程达给定的微秒数”,类似于C中的'usleep'。在这里,我们暂停执行,唯一的目的是给用户足够的时间按下Ctrl-C。 –

相关问题