gpt4 book ai didi

haskell - Control.Concurrent.Chan readChan 中的理论死锁

转载 作者:行者123 更新时间:2023-12-02 20:26:46 24 4
gpt4 key购买 nike

浏览readChan的源代码发现以下实现和注释,从base版本4.6开始:

-- |Read the next value from the 'Chan'.
readChan :: Chan a -> IO a
readChan (Chan readVar _) = do
modifyMVarMasked readVar $ \read_end -> do -- Note [modifyMVarMasked]
(ChItem val new_read_end) <- readMVar read_end
-- Use readMVar here, not takeMVar,
-- else dupChan doesn't work
return (new_read_end, val)

-- Note [modifyMVarMasked]
-- This prevents a theoretical deadlock if an asynchronous exception
-- happens during the readMVar while the MVar is empty. In that case
-- the read_end MVar will be left empty, and subsequent readers will
-- deadlock. Using modifyMVarMasked prevents this. The deadlock can
-- be reproduced, but only by expanding readMVar and inserting an
-- artificial yield between its takeMVar and putMVar operations.

在基础版本4.6之前,使用modifyMVar而不是modifyMVarMasked。

我不明白这里解决了什么理论问题。最后一句指出,如果线程在组成 readMVar 的 takeMVar 和 putMVar 之间让步,就会出现问题。但是当 readMVar 在 mask_ 下执行时,异步异常如何阻止成功 take 后的 put 呢?

如果您能帮助理解这里的问题,我们将不胜感激。

最佳答案

让我们比较一下 modifyMVarmodifyMVarMasked 的源代码,因为代码从使用一个更改为使用另一个:

modifyMVar m io =
mask $ \restore -> do
a <- takeMVar m
(a',b) <- restore (io a) `onException` putMVar m a
putMVar m a'
return b

modifyMVarMasked m io =
mask_ $ do
a <- takeMVar m
(a',b) <- io a `onException` putMVar m a
putMVar m a'
return b

这里的关键是 modifyMVar 在执行第二个参数之前调用 restore,而 modifyMVarMasked 则不会。因此,正如您在问题中声称的那样,在旧版本代码的 mask_ 下,readMVar 没有被调用!相反,它是在 restore 下调用的,因此毕竟可以启用异步异常。

关于haskell - Control.Concurrent.Chan readChan 中的理论死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21742932/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com