进程池&线程池
进程池&线程池
- 无论是开进程还是开线程,都需要消耗资源,只不过开线程的消耗比开进程消耗少一点而已。
- 不可能无限制的开进程或线程,因为计算机硬件的资源根不上。
- 为了保证服务器一定的处理能力,只能采取
池
的概念。 - 池:保证计算机稳定运行的前提下,再谈处理能力。虽然降低了效率,但保证了服务的稳定性。
基本使用:concurrent.futures模块
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
pool = ProcessPoolExecutor(5) # 设置池子的大小
pool.submit(task, i).add_done_callback(call_back) # 异步提交任务,回调处理收集结果
总结:
- 池子一旦造出来后,固定了线程或进程 "服务员",不会再变更,所有的任务都是这些"服务员"处理。
- 这些"服务员"不会再出现重复创建和销毁的过程。
- 任务的提交是异步的,异步提交任务的返回结果 应该通过回调机制来获取。
- 回调机制就相当于,把任务交给一个员工完成,它完成后主动找你汇报完成结果。
示例
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
import time
import os
# pool = ThreadPoolExecutor(5) # 池子里面固定只有五个线程
# 括号内可以传数字 不传的话默认会开设当前计算机cpu个数五倍的线程
pool = ProcessPoolExecutor(5)
# 括号内可以传数字 不传的话默认会开设当前计算机cpu个数进程
def task(n): # 处理任务的函数
print(n,os.getpid())
time.sleep(2)
return n**n
def call_back(n): # 回调处理数据的函数
print('call_back>>>:',n.result()) # obj.result() 拿到的就是异步提交的任务的返回结果
if __name__ == '__main__':
for i in range(20): # 朝池子中提交20个任务
res = pool.submit(task, i).add_done_callback(call_back)
# 将res返回的结果 <Future at 0x100f97b38 state=running>,交给回电函数 call_back处理
# 即res做实参传给call_back函数
map用法
- map = submit + for循环多次提交任务
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import os,time,random
def task(n):
print('%s is runing' %os.getpid())
time.sleep(random.randint(1,3))
return n**2
if __name__ == '__main__':
executor=ThreadPoolExecutor(max_workers=3)
# for i in range(11):
# future=executor.submit(task,i)
executor.map(task,range(1,12)) # map取代了for+submit