Я создал эту небольшую программу, которая создает долго работающий преобразователь, который в конечном итоге завершается ошибкой с исключением. Затем несколько потоков пытаются его оценить.
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 ())
подтверждает, что каждый поток терпит неудачу с исключением.
ghc-heap-view
, поэтому я не уверен, что еще вам нужно. Не могли бы вы уточнить свой вопрос, если мой ответ недостаточно полезен? - person Joachim Breitner   schedule 07.08.2013