gpt4 book ai didi

haskell - 为什么指向 MVar 的弱指针最终确定了,即使 MVar 仍然可以访问?

转载 作者:行者123 更新时间:2023-12-02 02:15:44 25 4
gpt4 key购买 nike

我看到混合使用 MVar 和 Weak 时出现问题:即使 MVar 仍然可以从函数的范围访问(并且主线程正在阻塞它),Weak 认为它应该被最终确定。这种行为似乎只有在启用优化的情况下编译时才会发生。

平台:64 位 Linux

使用 GHC 版本转载:6.10.4、6.12.3、7.0.4、7.2.2、7.4.1

module Main (main) where

import Control.Concurrent
import Control.Monad (forever, forM_)
import Data.IORef
import System.Mem
import System.Mem.Weak

dispatchPendingCalls :: IORef [Weak (MVar ())] -> IO ()
dispatchPendingCalls ref = forever $ do
threadDelay 100000

pending <- atomicModifyIORef ref (\p -> ([], p))
forM_ pending (\weak -> do
maybeMVar <- deRefWeak weak
case maybeMVar of
Just mvar -> putMVar mvar ()
Nothing -> putStrLn "dispatchPendingCalls: weak mvar is Nothing")

call :: IORef [Weak (MVar ())] -> IO ()
call ref = do
mvar <- newEmptyMVar
weak <- mkWeakPtr mvar (Just (putStrLn "call: finalising weak"))

putStrLn "call: about to insert weak into list"
atomicModifyIORef ref (\p -> (weak : p, ()))
putStrLn "call: inserted weak into list"
performGC
takeMVar mvar
putStrLn "call: took from mvar"

main :: IO ()
main = do
pendingCalls <- newIORef []
_ <- forkIO (dispatchPendingCalls pendingCalls)
call pendingCalls

预期输出:

$ ghc --make WeakMvar.hs
$ ./WeakMvar
call: about to insert weak into list
call: inserted weak into list
call: took from mvar
$

实际输出:

$ ghc --make -O2 WeakMvar.hs
$ ./WeakMvar
call: about to insert weak into list
call: inserted weak into list
call: finalizing weak
dispatchPendingCalls: weak mvar is Nothing
(never exits)

为什么会这样?如果我正确阅读了 System.Mem.Weak 文档,那么 takeMVar mvar 行应该使 mvar 保持事件状态,从而保持其弱指针有效。相反,弱指针认为 MVar 在 takeMVar 调用返回之前变得不可访问。

最佳答案

尝试在 call 中的 takeMVar 中捕获 BlockedIndefinitelyOnMVar(默认 IIR 处理,因此您不会看到它)。我想使用 Weak 可以防止 GC 注意到您对 dispatchPendingCalls 中的 MVar 的引用,所以它会被垃圾收集?

关于haskell - 为什么指向 MVar 的弱指针最终确定了,即使 MVar 仍然可以访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10802322/

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