gpt4 book ai didi

multithreading - 如何将 parMap 与一元函数一起使用?

转载 作者:行者123 更新时间:2023-12-04 00:59:34 25 4
gpt4 key购买 nike

我有一个单子(monad)函数getRate:

getRate :: String -> IO Double

我想将此函数映射到字符串列表。通常,我会这样做:
mapM getRate ["foo", "bar"]

但由于每次调用 getRate 都会进行网络调用,我想并行化 map ,以便在单独的线程中获取每个速率(或至少在队列中展开)。我在想类似的东西
parMapM getRate ["foo", "bar"]

但是没有 parMapM 函数,并且 parMap 不适用于 monadic 函数。

我能做些什么?

最佳答案

您应该使用 Control.Concurrent 并围绕 Control.Concurrent.MVar 进行同步;就像是:

fork1 :: (a -> IO b) -> a -> IO (MVar b)
fork1 f x =
do
cell <- newEmptyMVar
forkIO (do { result <- f x; putMVar cell result })
return cell

fork :: (a -> IO b) -> [a] -> IO [MVar b]
fork f = mapM (fork1 f)

join :: [MVar b] -> IO [b]
join = mapM takeMVar

forkJoin :: (a -> IO b) -> [a] -> IO [b]
forkJoin f xs = (fork f xs) >>= join

这部分(fork,join)看起来是连续的。在实践中发生的情况是线程在 fork 中顺序触发,并且集合点依次遍历等待每个线程。但是 IO 是同时发生的。

请注意,如果您需要调用外部函数,您应该使用 forkOS而不是 forkIO。

关于multithreading - 如何将 parMap 与一元函数一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2233452/

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