python多线程多进程concurrent.futures详细总结
1. 基本代码
import concurrent.futures
def f(i):
print(i)
return i
if __name__ =='__main__':
with concurrent.futures.ProcessPoolExecutor(max_workers=4)as executor:
futures =[executor.submit(f, i)for i in range(10)]
for future in concurrent.futures.as_completed(futures):
sult())
ption():
ption())
2. 代码解释
通过以上⽅式就可以多个进程同时运⾏f函数, sult() 是函数返回的i, max_worker 是进程/线程数, 默认为 CPU 核⼼数, f 为要执⾏的函数, i 为传给 f 的参数, 其中 ProcessPoolExecutor 多进程可以替换为 ThreadPoolExecutor 多线程, 通过查资料发现:
ProcessPool is for CPU bound tasks so you can benefit from multiple CPU.
Threads is for io bound tasks so you can benefit from io wait.
如果是IO密集多尽量⽤多线程, CPU密集尽量⽤多进程.
2. 异常处理
运⽤多进程/多线程的时候函数报错并不⼀定会直接结束程序, ⽽有可能会什么都不发⽣, 这样需要在 as_completed 之后捕捉异常, ⽤上⾯代码所⽰语句就可以.
3. submit和map的区别
上⾯是 submit 函数, 还有另⼀种 map 函数的⽤法
import concurrent.futures
def f(i):
print(i)
return i
if __name__ =='__main__':
with concurrent.futures.ProcessPoolExecutor(max_workers=4)as executor:
futures = executor.map(f,range(10))
# 等执⾏完全部返回
print(futures)
for future in futures:
print(future)
map 函数会⽐ submit 更简洁, 但是没法对返回⼀个⼀个处理, ⽽ submit 的好处是可以对每个返回在执⾏完成的瞬间处理, 不⽤等到每个线程/进程都执⾏完毕.
4. 注意
我⾃⼰⽤过很多次这个模块, 也遇到过很多坑, 以下是⼀些需要注意的地⽅
该模块⼀定要写在 if __name__ == '__main__' 之后, 否则很容易报错
不能同时操作⼀个 class , 会报错, 要想操作类都是每个进程分别操作新的类, 如: futures = [executor.submit(Class().fun(), i) for i in range(10)]
5. ⼯程代码⽰例
def get_data(self, workers=5):
total_data ={
'data':[],
'status_code':0
}
一个线程可以包含多个进程with concurrent.futures.ProcessPoolExecutor(max_workers=workers)as executor:
futures =[executor.submit(self.analyze, patent_number)for patent_number in self.patent_number_list]
for future in concurrent.futures.as_completed(futures):
# add result to total data
total_data['data'].sult())
return total_data
以上代码是在每个进程结束之后, 将数据添加到 total_data ⾥⾯, 最终返回 total_data .
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论