0

我有一些简单的代码以固定的时间间隔打印到屏幕上,除非IORef设置为指示用户当前正在输入:

import Data.IORef
import Control.Concurrent

main = do
   amTyping <- newIORef False
   forkIO $ printALot amTyping
   aChar <- getChar
   writeIORef amTyping True
   aLine <- getLine
   writeIORef amTyping False
   putStrLn $ aChar : aLine
   main

printALot :: IORef Bool -> IO ()
printALot theRef = do
   putStrLn "1111111"
   threadDelay 1000000
   isTyping <- readIORef theRef
   if isTyping
      then return ()
      else printALot theRef

这在 GHCi 中工作得很好,但是当我将它与 runghc 一起使用(或编译它)时,读取或写入IORef似乎不起作用——printALot只是继续循环,超出用户键入的任何内容。

ghci 和 runghc/compiled 之间有什么区别?我是不是用IORef错了,但没有注意到,因为 ghci 不是真正的多线程?

4

1 回答 1

8

这与并发无关。

您的解释程序和编译程序在它们使用的终端模式上有所不同:non-canonical 与 canonical

在规范模式下,您的程序在整行可用之前无法获取字符 - 因此您正在观察效果。

要解决此问题,只需将句柄置于非缓冲模式:

import System.IO

main = do
   hSetBuffering stdin NoBuffering
   ...
于 2013-01-03T09:06:18.193 回答