控制线程退出haskell应用程序

时间:2011-04-08 02:34:29

标签: haskell concurrency asynchronous io

我是Haskell的新手,并且在处理一些样本时,我遇到了一个无法阻止程序的问题。我正在使用Windows 7并使用ght的runhaskell。 Ctrl-c不起作用,所以我不得不诉诸任务管理器,这有点痛苦。

如何创建一个单独的控制线程,等待我输入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

2 个答案:

答案 0 :(得分:5)

您应该可以使用Haskell线程getChar执行此操作并退出{With,Success,Failure}。

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 :(得分:0)

  

如何创建一个单独的控制线程,等待我输入q然后退出我的Haskell应用程序。

您可以使用forkIO创建新线程,它将一大块代码作为参数。 E.g。

main = do
    forkIO waitForQuit
    ....

退出处理程序将大部分时间都用在getChar上,但是当它被唤醒时,它可以通过抛出退出异常来终止程序,例如:

    exitWith ExitSuccess

您可能需要使用ghc -O -threaded编译程序以确保程序主线程可以取得进展,而处理程序正在等待q