gpt4 book ai didi

multithreading - 使用 Haskell 的 MVar 包,但使用 seq 强制执行严格性

转载 作者:行者123 更新时间:2023-12-04 06:51:51 24 4
gpt4 key购买 nike

在关于 hackage 的 Control.Concurrent.MVar 文档中,我们有一个关于 MVar 用法的“陷阱”。这是 link .

MVar 表示,当您使用 putMVar 将内容放入 MVar 时,如果您放入的内容是一个巨大的 thunk,接收线程将具有评估的困惑工作,而不是发送线程。

除了可能令人讨厌或没有根据之外,为了补救这种情况,它向我们指出了 evaluate 的方向,它本身说要使用 seq。每个人最喜欢的 haskell 函数。

Evaluate的语义应该是这样的:

evaluate x `seq` y    ==>  y

所以我的问题是:为什么这不会在 fork 线程中求值!?!?!

concTreeMap :: (a -> b) -> BinaryTree a -> IO (BinaryTree b)
concTreeMap f Leaf = return Leaf
concTreeMap f (Branch v l r) = do
res <- newEmptyMVar
forkIO $ do
let fv = f v
evaluate fv `seq` (putMVar res fv)
v' <- takeMVar res
l' <- concTreeMap f l
r' <- concTreeMap f r
return (Branch v' l' r')

编辑以添加等效的加速...

不知何故,这相当于下面的答案(不使用评估,而是使用 seq)...无论如何,我认为加速的要点在于 a) 向 haskell 运行时提供有关 thunk 评估的提示和 2) 移动从看跌期权中拿走

concTreeMap :: (a -> b) -> BinaryTree a -> IO (BinaryTree b)
concTreeMap f Leaf = return Leaf
concTreeMap f (Branch v l r) = do
res <- newEmptyMVar
forkIO $ do { let fv = f v in fv `seq` putMVar res fv }
l' <- concTreeMap f l
r' <- concTreeMap f r
v' <- takeMVar res
return (Branch v' l' r')

最佳答案

假设您按照 Petr Pudlák 的回答修复了您的程序,您试图在启动线程后立即从 MVar 中获取一个值。所以你没有并行性,因为运行 concTreeMap 的线程必须等待 MVar 已满,这意味着等待 fork 线程放置 fvMVar 中,直到它对其求值后才这样做。与此同时,原始线程什么也不做。

你不是想写吗

  ...
forkIO $ do
let fv = f v
evaluate fv `seq` (putMVar res fv)
l' <- concTreeMap f l
r' <- concTreeMap f r
v' <- takeMVar res -- Note: this moved to after we do more work
return (Branch v' l' r')

?

关于multithreading - 使用 Haskell 的 MVar 包,但使用 seq 强制执行严格性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31074264/

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