Управляющий поток для выхода из приложения haskell - PullRequest
3 голосов
/ 08 апреля 2011

Я новичок в Haskell и, возясь с несколькими образцами, у меня возникла проблема, когда я не могу остановить программу.Я использую Windows 7 и использую runhaskell от GHT.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 ]

5 голосов
/ 08 апреля 2011

Вы должны быть в состоянии сделать это с потоком на 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.Обратите внимание, что это не отдельный поток ОС, а поток Haskell, который очень легкий.Поток exitOnQ должен получать нажатия клавиш без задержки - без NoBuffering вы должны были бы нажать q- [ENTER].Если нажатой клавишей не было q (или Q), то мы выполняем цикл, в противном случае мы завершаем программу одним из множества вызовов exit*.

ВНИМАНИЕ: Это очень необычный случай в углу, но GHC использует точки GC в качестве точек планирования потоков (изменилось ли это за последние два года?), поэтому, если ваш код тратит значительные блоки времени на выполнение множества чистых вычислений с нулевым распределением, вы не сможете использовать этот метод для выхода(если у вас нет нескольких потоков ОС с помощью многопоточных RTS и и опции +RTS -N#).

0 голосов
/ 08 апреля 2011

как создать отдельный поток управления, который будет ждать, пока я наберу q, а затем выйду из приложения на Haskell.

Вы можете создавать новые потоки с forkIO, который принимает кусок кода в качестве аргумента. Э.Г.

main = do
    forkIO waitForQuit
    ....

Обработчик выхода будет проводить большую часть своего времени заблокированным на getChar, но когда он просыпается, он может завершить программу, вызывая исключение при выходе, например:

    exitWith ExitSuccess

Вам может потребоваться скомпилировать программу с помощью ghc -O -threaded, чтобы гарантировать, что основной поток программы может продвигаться, пока обработчик ожидает q

...