2011-04-08 34 views
3

我是Haskell的全新用戶,並在一些示例中弄亂了我遇到的問題,無法停止該程序。我正在使用Windows 7並使用ght的runhaskell。 Ctrl-c不起作用,所以我不得不訴諸任務管理器,這有點痛苦。控制線程退出haskell應用程序

而不是如何創建一個單獨的控制線程,直到我鍵入q然後退出我的Haskell應用程序。

我已經得到了問題的應用程序的格式爲:

main = do 
h <- connectTo server (PortNumber (fromInteger port)) 
hSetBuffering h NoBuffering 
... do some stuff with the socket handle ... 
listen h 

listen :: Handle -> IO() 
listen h = forever $ do 
    t <- hGetLine h 
    let s = init t 
    putStrLn s 
where 
    forever a = do a; forever a 

在僞代碼想什麼,我已經是:

main = do 
    waitForQuit 
    ... original program ... 

waitForQuit :: IO() 
    option <- getChar 
    if option == 'q' then 
    ... kill the app ... 
    else 
    waitForQuit 

回答

5

您應該可以使用Haskell線程getChar並退出{With,Success,F ailure}。

import Control.Concurrent 
import System.Exit 
import Data.Char (toLower) 
import System.IO 

main = do 
    forkIO realMain 
    exitOnQ 

exitOnQ = do 
    hSetBuffering stdin NoBuffering 
    c <- getChar 
    when (toLower c /= 'q') exitOnQ 
    exitSuccess -- or "exitWith" and some ExitCode value, use hoogle. 

打破下來:你可以通過forkIO得到兼任。注意這不是一個單獨的OS線程,而是一個非常輕量級的Haskell線程。 exitOnQ線程需要立即得到擊鍵 - 沒有NoBuffering,你必須按q- [ENTER]。如果按下的鍵不是q(或Q),那麼我們循環,否則我們通過多個exit*調用之一終止程序。

警告:這是一個非常罕見的角落案例,但GHC使用GC點作爲線程調度點(這在過去兩年有所變化?),所以如果您的代碼花費大量時間執行大量純計算有零分配,則不能使用此方法退出(除非通過線程RTS +RTS -N#選項有多個OS線程)。

+1

程序僅在主線程退出時退出,因此您需要交換'...'和'exitOnQ'。在額外的線程中執行工作,主要是'exitWith''。 – barsoap 2012-10-15 15:38:47

1

怎麼可以創建一個單獨的控制線程,等待我輸入q然後退出我的Haskell應用程序。

您可以使用forkIO創建新線程,它將一大塊代碼作爲參數。例如。

main = do 
    forkIO waitForQuit 
    .... 

的退出處理程序將花費其大部分時間封鎖getChar,但是當它醒來時,它可以終止程序,通過拋出一個出口異常,如:

exitWith ExitSuccess 

您可能需要使用ghc -O -threaded來編譯程序,以確保程序主線程可以取得進展,而處理程序正在等待q