16

私は、最終的に例外で失敗する長時間実行サンクを作成するこの小さなプログラムを作成しました。次に、複数のスレッドがそれを評価しようとします。

import Control.Monad
import Control.Concurrent
import Control.Concurrent.MVar

main = do
    let thunk = let p = product [1..10^4]
                 in if p `mod` 2 == 0 then error "exception"
                                      else ()
    children <- replicateM 2000 (myForkIO (print thunk))
    mapM_ takeMVar children

-- | Spawn a thread and return a MVar which can be used to wait for it.
myForkIO :: IO () -> IO (MVar ())
myForkIO io = do
     mvar <- newEmptyMVar
     forkFinally io (\_ -> putMVar mvar ())
     return mvar

スレッドの数を増やしても、明らかに計算に影響はありません。これは、失敗したサンクが結果として例外を保持することを示唆しています。本当ですか?この動作はどこかに文書化/指定されていますか?

更新:forkFinally行を次のように変更します

forkFinally io (\e -> print e >> putMVar mvar ())

各スレッドが例外で失敗することを確認します。

4

1 に答える 1