私はこの長期的なサンクを作成し、最終的には例外で失敗する小さなプログラムを作成しました。次に、複数のスレッドが評価しようとします。サンクが発生した場合、そのサンクの結果として例外が保持されますか?
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 io (\e -> print e >> putMVar mvar())
にforkFinally
ラインを変更するには、各スレッドが例外で失敗したことを確認します。
例外*は*式の値です。他に何回表現を評価することができますか? – Carl
@Carlそれは私が疑うところですが、私は確信したいと思います。また、値を何度も再計算してみることもできます。 –
私はGHCの内部構造を知っています。そうでなければ 'ghc-heap-view'のようなツールを作ることができませんでしたので、もっと何が必要なのか分かりません。私の答えが十分役に立たない場合は、あなたの質問を明確にしてもらえますか? –