【问题标题】:Control thread to exit haskell application控制线程退出haskell应用程序
【发布时间】:2011-08-01 04:19:43
【问题描述】:

我是 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

【问题讨论】:

    标签: haskell concurrency asynchronous io


    【解决方案1】:

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

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

    main = do
        forkIO waitForQuit
        ....
    

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

        exitWith ExitSuccess
    

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

    【讨论】:

    • 这不行,从一个线程调用exitWith只会杀死那个线程。
    【解决方案2】:

    您应该能够使用 Haskell 线程、getChar 和 exit{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 获得。请注意,这不是一个单独的操作系统线程,而是一个非常轻量级的 Haskell 线程。 exitOnQ 线程需要立即获得击键 - 如果没有 NoBuffering,您必须按 q-[ENTER]。如果按下的键不是q(或Q),则循环,否则我们通过许多exit* 调用之一终止程序。

    警告:这是一个非常罕见的极端情况,但 GHC 使用 GC 点作为线程调度点(这在过去两年中发生了变化吗?)所以如果您的代码花费大量时间执行大量纯计算零分配,那么您不能使用此方法退出(除非您有多个操作系统线程通过线程 RTS +RTS -N# 选项)。

    【讨论】:

    • 程序只有在主线程退出时才会退出,所以需要交换...exitOnQ。在额外线程中完成工作,主线程中的exitWith'ing。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-07
    • 2010-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多