我正在尝试编写一个输出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演员来完成类似的任务。但似乎人们试图避开哈斯克尔的演员。
答案 0 :(得分:4)
是的,这是一个缓冲问题。导入System.IO
,然后将hSetBuffering stdout NoBuffering
添加到main
的开头以修复它。是的,您可以使用forkIO
进行并发。如果您想要多个OS线程可用,请不要忘记使用-threaded
进行编译并使用+RTS -N
或类似程序运行您的程序。