Multithreading 循环线程在没有'hFlush stdout'的情况下挂起,即使没有'print'内容
当我测试一些关于线程代码的简单案例时,Multithreading 循环线程在没有'hFlush stdout'的情况下挂起,即使没有'print'内容,multithreading,loops,haskell,freeze,Multithreading,Loops,Haskell,Freeze,当我测试一些关于线程代码的简单案例时, 我发现一些循环挂起时没有hFlush标准输出,即使它不使用任何打印东西 import Control.Concurrent import System.IO import Data.IORef delay :: Int -> IO () delay = threadDelay . (* 1000000) wait sw = loop where loop = do v <- readIORef sw -
我发现一些循环挂起时没有
hFlush标准输出
,即使它不使用任何打印
东西
import Control.Concurrent
import System.IO
import Data.IORef
delay :: Int -> IO ()
delay = threadDelay . (* 1000000)
wait sw = loop
where
loop = do
v <- readIORef sw
--hFlush stdout -- without this, hang
if v
then return()
else loop
monitor sw = forkIO $ loop
where
loop = do
v <- readIORef sw
print v
delay 1
loop
main = do
sw <- newIORef False
forkIO $ do
delay 4
writeIORef sw True
monitor sw
wait sw
--putStrLn "End"
通过runghc
运行时,这两个代码将正常运行
但是,如果没有hFlush标准输出,
以下代码不会挂起
import Control.Concurrent
import Control.Concurrent.MVar
import System.IO
delay :: Int -> IO ()
delay = threadDelay . (* 1000000)
wait :: MVar Bool -> IO ()
wait sw = loop
where loop = do
v <- readMVar sw
if v
then return ()
else loop
main :: IO ()
main = do
sw <- newEmptyMVar
forkIO $ do
delay 4
putMVar sw True
wait sw
导入控制。并发
导入控制.Concurrent.MVar
导入系统.IO
延迟::Int->IO()
延迟=线程延迟。(* 1000000)
等待::MVar Bool->IO()
等待sw=循环
其中loop=do
v IO()
wait sw=原子级$do
v编译器很可能将wait
优化为非分配忙循环。运行时系统只是没有机会中断它,让子线程运行。您可以通过添加任何分配或产生的操作来“修复”,例如hFlush
或threadDelay
。您还可以使用-fno-ommit
编译代码
另请参见:和编译器很可能将等待
优化为非分配忙循环。运行时系统只是没有机会中断它,让子线程运行。您可以通过添加任何分配或产生的操作来“修复”,例如hFlush
或threadDelay
。您还可以使用-fno-ommit
编译代码
另请参见:和除上一个STM版本外,所有这些函数都是低效的忙循环。他们的设计只是让他们挂起来。这就是为什么STM如此好的部分原因:你得到了你所期望的,而不是不得不担心暂时的问题。我希望hFlush stdout
只是作为一个随机延迟。测试确认,将hFlush stdout
替换为randomRIO(1,10^3)>=delay
会产生相同的行为。在monitor
@Joehillen中有print
是的,在monitor
中有print
。但是,当注释或删除监视器时,代码挂起。你可以尝试摆脱任何打印的东西。除了上一个STM版本外,所有这些函数都是低效的忙循环。他们的设计只是让他们挂起来。这就是为什么STM如此好的部分原因:你得到了你所期望的,而不是不得不担心暂时的问题。我希望hFlush stdout
只是作为一个随机延迟。测试确认,将hFlush stdout
替换为randomRIO(1,10^3)>=delay
会产生相同的行为。在monitor
@Joehillen中有print
是的,在monitor
中有print
。但是,当注释或删除监视器时,代码挂起。你可以尝试摆脱任何print
东西。标准的“产生效果的行动”是。谢谢,我能理解问题所在。标准的“产生效果的行动”是。谢谢,我能理解问题所在。
import Control.Concurrent
import Control.Concurrent.MVar
import System.IO
delay :: Int -> IO ()
delay = threadDelay . (* 1000000)
wait :: MVar Bool -> IO ()
wait sw = loop
where loop = do
v <- readMVar sw
if v
then return ()
else loop
main :: IO ()
main = do
sw <- newEmptyMVar
forkIO $ do
delay 4
putMVar sw True
wait sw
import Control.Concurrent
import Control.Concurrent.STM
import Control.Concurrent.STM.TVar
import System.IO
delay :: Int -> IO ()
delay = threadDelay . (* 1000000)
wait :: TVar Bool -> IO ()
wait sw = atomically $ do
v <- readTVar sw
unless v retry
main :: IO ()
main = do
sw <- newTVarIO False
forkIO $ do
delay 4
atomically $ writeTVar sw True
wait sw