控制线程退出haskell应用程序

发布于 2024-10-31 06:24:51 字数 744 浏览 3 评论 0原文

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

I'm brand new to Haskell and in messing around with a few samples I've got a problem where I can't stop the program. I'm using Windows 7 and using runhaskell from ght. Ctrl-c doesn't work so I have to resort to the task manager which is a bit of a pain.

Instead of doing that how can I create a separate control thread that would wait until I typed q and then quit my Haskell application.

The application I've got the problem with is of the format:

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

In pseudo-code what I'd like to have is:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最美不过初阳 2024-11-07 06:24:51

您应该能够使用 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# 选项拥有多个操作系统线程)。

You should be able to do this with a Haskell thread, getChar and 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.

Breaking this down: You get concurrently via forkIO. Notice this isn't a separate OS thread, but a Haskell thread which is extremely lightweight. The exitOnQ thread needs to get keystrokes without delay - without the NoBuffering you'd have to hit q-[ENTER]. If the pressed key wasn't q (or Q) then we loop, otherwise we terminate the program via one of the many exit* calls.

WARNING: It is a very uncommon corner case, but GHC uses GC points as thread scheduling points (has this changed in the past two years?) so if your code is spending significant blocks of time performing lots of pure computations that have zero allocation then you can't use this method to quit (unless you have multiple OS threads via the threaded RTS and an +RTS -N# option).

笙痞 2024-11-07 06:24:51

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

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

main = do
    forkIO waitForQuit
    ....

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

    exitWith ExitSuccess

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

how can I create a separate control thread that would wait until I typed q and then quit my Haskell application.

You can create new threads with forkIO, which takes a chunk of code as an argument. E.g.

main = do
    forkIO waitForQuit
    ....

The quit handler will spend most of its time blocked on getChar, but when it wakes up, it can terminate the program, by throwing an exit exception, such as:

    exitWith ExitSuccess

You may need to compile the program with ghc -O -threaded to ensure the program main thread can make progress, while the handler is waiting on q

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文