我有一些简单的代码以固定的时间间隔打印到屏幕上,除非设置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 /编译之间的区别是什么?我使用IORef
错了,但没有注意到因为ghci不是真正的多线程吗?
答案 0 :(得分:8)
这与并发无关。
您的解释和编译程序在他们使用的终端模式方面有所不同:non-canonical vs canonical。
在规范模式中,你的程序在整行可用之前没有得到角色 - 因此你正在观察的效果。
要解决此问题,只需将手柄置于非缓冲模式:
import System.IO
main = do
hSetBuffering stdin NoBuffering
...