Multithreading 哈斯克尔';s'putChar'不';如果与“threadDelay”一起使用,则不会打印任何内容>;1秒

Multithreading 哈斯克尔';s'putChar'不';如果与“threadDelay”一起使用,则不会打印任何内容>;1秒,multithreading,haskell,Multithreading,Haskell,我试图编写一个简单的程序,输出xoxoxoxoxoxoxoxooxxxxxoo字符串 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 如果我对thr

我试图编写一个简单的程序,输出
xoxoxoxoxoxoxoxooxxxxxoo
字符串

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
如果我对
threadDelay
使用大值(
1
second或
0.1
second),它不会打印任何内容,直到我按任意键(程序打印输出并明显退出)

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

出现了两个问题

首先。这是终端缓冲问题吗?还是哈斯凯尔?我可以禁用它吗

第二。我可以使用这种技术为服务器编写一个游戏循环,该服务器具有多个独立计算状态的游戏室吗?就像你为两个开始战斗的玩家创建一个房间一样,
forkIO
thread做所有的计算,每秒30次向玩家报告更新的状态


你能推荐最好的线程通信模式吗?STM?过去,我曾使用Erlangs actors执行类似的任务。但似乎人们在哈斯凯尔试图避开演员。

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

是的,这可能是缓冲问题。你想要的功能是。当您设置一个非常小的延迟时,当字符超过一行的长度时,您的终端可能会刷新缓冲区(这对于10ms的延迟来说是非常快的)。我不知道第二个问题是什么意思-你指的是什么“技巧”?当然,您可以在以
forkIO
开头的线程中执行任意计算,就像您可以在主线程中执行一样。最后一个问题(库建议)与主题无关。请尝试
hFlush stdout
putChar
@user2407038之后,该问题不会询问库。它询问“线程通信模式”。