【发布时间】:2012-04-20 13:47:23
【问题描述】:
我正在尝试在 Haskell 中使用并发进行特定优化,其中只需要两个值中的一个,并且根据具体情况,创建其中一个值可能比另一个快得多。
我想我可以只用 forkIO 运行 2 个线程,然后等到一个值放入 MVar。这是我为此编写的一个简单测试:
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 真的不应该花费那么多时间)。为什么会这样,我该如何解决?
【问题讨论】:
-
你如何运行你的代码?默认情况下,haskell 使用轻线程而不是真正的操作系统线程。我不知道细节,但这可能会改变很多调度策略。
-
可能不适合您的情况,但您也可能会研究一些关于“推测并行性”的工作:hackage.haskell.org/package/speculation
-
仅供参考,hackage.haskell.org/package/monad-par 公开了一个相当不错的、外部纯并行 API,但仍允许您明确声明分叉、连接等。
标签: haskell concurrency