Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 循环线程在没有'hFlush stdout'的情况下挂起,即使没有'print'内容_Multithreading_Loops_Haskell_Freeze - Fatal编程技术网

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