ghci和runghc中的不同并发行为

时间:2013-01-03 05:54:46

标签: haskell concurrency ghc

我有一些简单的代码以固定的时间间隔打印到屏幕上,除非设置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不是真正的多线程吗?

1 个答案:

答案 0 :(得分:8)

这与并发无关。

您的解释和编译程序在他们使用的终端模式方面有所不同:non-canonical vs canonical

在规范模式中,你的程序在整行可用之前没有得到角色 - 因此你正在观察的效果。

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

import System.IO

main = do
   hSetBuffering stdin NoBuffering
   ...