python线程池和进程池_python并发——线程池与进程池(转)

Python中进行并发编程一般使用threading和multiprocessing模块,不过大部分的并发编程任务都是派生一系列线程,从队列中收集资源,然后用队列收集结果。在这些任务中,往往需要生成线程池,concurrent.futures模块对threading和multiprocessing模块进行了进一步的包装,可以很方便地实现池的功能。

Executor与Future

concurrent.futures供了ThreadPoolExecutor和ProcessPoolExecutor两个类,都继承自Executor,分别被用来创建线程池和进程池,接受max_workers参数,代表创建的线程数或者进程数。ProcessPoolExecutor的max_workers参数可以为空,程序会自动创建基于电脑cpu数目的进程数。

from concurrent.futures importThreadPoolExecutor, ProcessPoolExecutorimportrequestsdefload_url(url):returnrequests.get(url)

url= 'http://httpbin.org'executor= ThreadPoolExecutor(max_workers=1)

future= executor.submit(load_url, url)

Executor中定义了submit()方法,这个方法的作用是提交一个可执行的回调task,并返回一个future实例。future能够使用done()方法判断该任务是否结束,done()方法是不阻塞的,使用result()方法可以获取任务的返回值,这个方法是阻塞的。

Future类似于js中的Promise,可以添加回调函数:

回调函数fn在future取消或者完成后运行,参数是future本身。

submit()方法只能进行单个任务,用并发多个任务,需要使用map与as_completed。

map

URLS = ['http://httpbin.org', 'http://example.com/', 'https://api.github.com/']defload_url(url):returnrequests.get(url)

with ThreadPoolExecutor(max_workers=3) as executor:for url, data inzip(URLS, executor.map(load_url, URLS)):print('%r page status_code %s' % (url, data.status_code))

map方法接收两个参数,第一个为要执行的函数,第二个为一个序列,会对序列中的每个元素都执行这个函数,返回值为执行结果组成的生成器。

由上面可以看出返回结果与序列结果的顺序是一致的

as_completed

as_completed()方法返回一个Future组成的生成器,在没有任务完成的时候,会阻塞,在有某个任务完成的时候,会yield这个任务,直到所有的任务结束。

defload_url(url):returnurl, requests.get(url).status_code

with ThreadPoolExecutor(max_workers=3) as executor:

tasks= [executor.submit(load_url, url) for url inURLS]for future inas_completed(tasks):print future.result()

可以看出,结果与序列顺序不一致,先完成的任务会先通知主线程。

wait

wait方法可以让主线程阻塞,直到满足设定的要求。有三种条件ALL_COMPLETED, FIRST_COMPLETED,FIRST_EXCEPTION。

from concurrent.futures importThreadPoolExecutor, ProcessPoolExecutor, wait, ALL_COMPLETED, FIRST_COMPLETEDfrom concurrent.futures importas_completedimportrequests

URLS= ['http://httpbin.org', 'http://example.com/', 'https://api.github.com/']defload_url(url):

requests.get(url)printurl

with ThreadPoolExecutor(max_workers=3) as executor:

tasks= [executor.submit(load_url, url) for url inURLS]

wait(tasks, return_when=ALL_COMPLETED)print 'all_cone'

ProcessPoolExecutor

使用ProcessPoolExecutor与ThreadPoolExecutor方法基本一致,注意文档中有一句:

The __main__ module must be importable by worker subprocesses. This means that ProcessPoolExecutor will not work in the interactive interpreter.

需要__main__模块。

defmain():

with ProcessPoolExecutor() as executor:

tasks= [executor.submit(load_url, url) for url inURLS]for f inas_completed(tasks):

ret=f.done()ifret:printf.result().status_codeif __name__ == '__main__':

main()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值