如果与`threadDelay`>一起使用,Haskell的`putChar`不会打印任何内容。 1秒

时间:2017-06-19 22:21:35

标签: multithreading haskell

我正在尝试编写一个输出xoxoxoxoxoooxoxxxxoxoo字符串的简单程序。

module Main where

import Control.Concurrent

loop :: Char -> IO ()
loop c = do
  putChar c
  threadDelay 1000000 -- 1 second
  loop c

main = do
  forkIO $ loop 'x'
  forkIO $ loop 'o'
  getChar

如果我对1使用大值(0.1秒或threadDelay秒),则在按任意键之前不打印任何内容(程序打印输出并显然退出)。

但是,如果我使用像10这样的小值,它会向终端打印大块字符。

出现两个问题。

首先。这是终端缓冲问题吗?或者Haskell以某种方式缓冲IO?我可以禁用吗?

二。我可以使用这种技术为具有独立计算状态的多个游戏室的服务器编写游戏循环吗?就像你为两个玩家开始战斗创建一个房间一样,forkIO线程做所有数学运算并且每秒30次报告更新状态回到玩家TCP套接字。

您是否还可以为此类任务推荐最佳线程通信模式? STM?我过去常常使用Erlangs演员来完成类似的任务。但似乎人们试图避开哈斯克尔的演员。

1 个答案:

答案 0 :(得分:4)

是的,这是一个缓冲问题。导入System.IO,然后将hSetBuffering stdout NoBuffering添加到main的开头以修复它。是的,您可以使用forkIO进行并发。如果您想要多个OS线程可用,请不要忘记使用-threaded进行编译并使用+RTS -N或类似程序运行您的程序。