Tôi tạo ra chương trình nhỏ này tạo ra một đoạn dài chạy mà cuối cùng thất bại với một ngoại lệ. Sau đó, nhiều chủ đề cố gắng để đánh giá nó.Nếu một kết quả trong một ngoại lệ, ngoại lệ có được lưu giữ như là kết quả của thunk không?
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
Tăng số lượng chủ đề rõ ràng không ảnh hưởng đến tính toán, điều này cho thấy một đoạn không thành công sẽ giữ ngoại lệ. Có đúng không? Hành vi này có được ghi lại/chỉ định ở đâu đó không?
Cập nhật: Thay đổi dòng forkFinally
để
forkFinally io (\e -> print e >> putMVar mvar())
khẳng định rằng mỗi thread không thành công với các ngoại lệ.
Ngoại lệ * là * giá trị của biểu thức. Điều gì khác có thể đánh giá biểu thức nhiều lần làm gì? – Carl
@Carl Đó là điều tôi nghi ngờ, nhưng tôi muốn chắc chắn. Nó cũng có thể thử tính lại giá trị một lần nữa và một lần nữa. –
Tôi biết nội bộ GHC, nếu không tôi không thể tạo các công cụ như 'ghc-heap-view', vì vậy tôi không chắc bạn cần thêm gì nữa. Bạn có thể làm rõ câu hỏi của bạn nếu câu trả lời của tôi không đủ hữu ích? –