Haskell的Control.Concurrent.Async.mapConcurrent可以有限制吗? [英] Can Haskell's Control.Concurrent.Async.mapConcurrently have a limit?

查看:70
本文介绍了Haskell的Control.Concurrent.Async.mapConcurrent可以有限制吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在Haskell中并行运行多个下载,通常只使用Control.Concurrent.Async.mapConcurrently函数.但是,这样做会打开约3000个连接,这将导致Web服务器拒绝所有连接.是否可以同时完成与mapConcurrent相同的任务,但是一次只能打开有限数量的连接(即一次只能打开2或4个连接)?

I'm attempting to run multiple downloads in parallel in Haskell, which I would normally just use the Control.Concurrent.Async.mapConcurrently function for. However, doing so opens ~3000 connections, which causes the web server to reject them all. Is it possible to accomplish the same task as mapConcurrently, but only have a limited number of connections open at a time (i.e. only 2 or 4 at a time)?

推荐答案

一种快速的解决方案是使用信号量以限制并发操作的数量.这不是最佳选择(所有线程都立即创建然后等待),但是可以正常工作:

A quick solution would be to use a semaphore to restrict the number of concurrent actions. It's not optimal (all threads are created at once and then wait), but works:

import Control.Concurrent.MSem
import Control.Concurrent.Async
import Control.Concurrent (threadDelay)
import qualified Data.Traversable as T

mapPool :: T.Traversable t => Int -> (a -> IO b) -> t a -> IO (t b)
mapPool max f xs = do
    sem <- new max
    mapConcurrently (with sem . f) xs

-- A little test:
main = mapPool 10 (\x -> threadDelay 1000000 >> print x) [1..100]

这篇关于Haskell的Control.Concurrent.Async.mapConcurrent可以有限制吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆