Bil*_*ill 12 parallel-processing monads concurrency multithreading haskell
我有一个monadic函数getRate:
getRate :: String -> IO Double
Run Code Online (Sandbox Code Playgroud)
我想将这个函数映射到String的列表上.通常情况下,我会这样做:
mapM getRate ["foo", "bar"]
Run Code Online (Sandbox Code Playgroud)
但是由于每次调用getRate进行网络调用,我都希望并行化地图,以便在一个单独的线程中获取每个速率(或者至少在队列中分散).我在想类似的东西
parMapM getRate ["foo", "bar"]
Run Code Online (Sandbox Code Playgroud)
但没有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
Run Code Online (Sandbox Code Playgroud)
这部分(fork,join)看起来是顺序的.在实践中发生的事情是线程在fork中顺序触发,并且集合点遍历等待每个线程.但IO同时发生.
请注意,如果需要调用外部函数,则应使用forkOS而不是forkIO.
还有一个monad-parallel包提供了mapM :: MonadParallel m =>(a - > mb) - > [a] - > m [b].查看MonadParallel的IO实例,它的方式与Dominic的答案相同.
| 归档时间: |
|
| 查看次数: |
835 次 |
| 最近记录: |