gpt4 book ai didi

Haskell 并发 - forkIO 真的是不确定的吗?

转载 作者:行者123 更新时间:2023-12-03 23:12:43 25 4
gpt4 key购买 nike

我正在尝试在 Haskell 中使用并发进行特定优化,其中只需要两个值中的一个,并且根据情况,创建其中一个值可能比另一个快得多。

我想我可以只用 forkIO 运行 2 个线程,然后等到一个值放入 M​​Var 中。这是我为此编写的一个简单测试:

import Control.Concurrent

main = do out <- newEmptyMVar
t1 <- forkIO (makeString out)
t2 <- forkIO (makeInt out)
v <- takeMVar out
killThread t1
killThread t2
case v of
Left s -> putStrLn s
Right i -> putStrLn $ show i

makeString out = do s <- return ( show (primes !! 10000))
putMVar out $ Left s

makeInt out = do i <- return 2
putMVar out $ Right i

primes = sieve [2..]
where sieve (x:xs) = x : (sieve $ filter ((/=0).(flip mod x)) xs)

编译:
ghc --make -threaded Test

然而,只有 Left 的情况下,尽管获得质数应该需要足够长的时间才能启动 makeInt 线程(并且 return 2 真的不应该花费那么多时间)。为什么会这样,我该如何解决?

最佳答案

这里的问题是懒惰。 makeString只是插入一个 thunk 来计算 show (primes !! 10000) ,然后由主线程评估。插入 thunk 非常快,因此在这种情况下它恰好赢得了比赛。

要强制在线程内进行评估,您可以更改 returnevaluate :

makeString out = do s <- evaluate $ show (primes !! 10000)
putMVar out $ Left s

这应该会导致 makeInt在大多数情况下赢得比赛(尽管不能保证)。

关于Haskell 并发 - forkIO 真的是不确定的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10247555/

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