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之后,该问题不会询问库。它询问“线程通信模式”。