以下似乎工作(如:口口聲聲說Surely tomorrow
每秒)
import Control.Concurrent
import Control.Concurrent.MVar
import Control.Exception (evaluate)
main :: IO()
main = do
godot <- newEmptyMVar
forkIO $ do
g <- evaluate $ last [0..]
putMVar godot g
let loop = do
threadDelay $ 10^6
g <- tryTakeMVar godot
case g of
Just g -> return()
Nothing -> putStrLn "Surely tomorrow." >> loop
loop
這使用evaluate
確保填充MVar
之前last [0..]
實際上是被迫WHFN - 如果我的分叉線程切換到
forkIO $ do
let g = last [0..]
putMVar godot g
然後程序終止。
但是,evaluate
使用seq
。在確定性並行性方面,總是強調seq
不足以實際保證評估順序。是否在一元範圍內不會出現這個問題,或者我應該更好地利用
forkIO $ do
let g = last [0..]
g `pseq` putMVar godot g
,以確保編譯器不能重新排序評估,使tryTakeMVar
成功過早?