1.concurrent.futures模块 直接内置就是 异步的提交   ,如果你想同步也可以实现(p.submit(task,i).result()即同步执行)

2.属性和方法:

  1.submit   提交

  2.shutdown  关闭池的入口  等池运行结束

 #进程池
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
import os,time,random
def task(n):
print('%s is running' %os.getpid())
time.sleep(2)
return n**2 if __name__ == '__main__':
p=ProcessPoolExecutor()
l=[]
start=time.time()
for i in range(10):
obj=p.submit(task,i)
l.append(obj)
p.shutdown()
print('='*30)
# print([obj for obj in l]) # 结果 都是 future 的对象 [<Future at 0x1461d97d1d0 state=finished returned int>,
# <Future at 0x1461d9c6438 state=finished returned int>]
print([obj.result() for obj in l])
print(time.time()-start)
# 结果:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
6.206435441970825

进程池

 # 线程池
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
import threading
import os,time,random
def task(n):
print('%s:%s is running' %(threading.currentThread().getName(),os.getpid()))
time.sleep(2)
return n**2 if __name__ == '__main__':
p=ThreadPoolExecutor()
l=[]
start=time.time()
for i in range(10):
obj=p.submit(task,i)
l.append(obj)
p.shutdown()
print('='*30)
print([obj.result() for obj in l])
print(time.time()-start) # 结果:
==============================
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
2.0046041011810303

线程池

  进程池 默认个数是CPU个数,而线程池的默认个数是CPU个数的5倍

补充:回调函数

 from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
import requests
import os
import time
from threading import currentThread
def get_page(url):
print('%s:<%s> is getting [%s]' %(currentThread().getName(),os.getpid(),url))
response=requests.get(url)
time.sleep(2)
return {'url':url,'text':response.text}
def parse_page(res):
res=res.result() #与Pool不同之处,这里的res得到的是对象,需要result一下
print('%s:<%s> parse [%s]' %(currentThread().getName(),os.getpid(),res['url']))
with open('db.txt','a') as f:
parse_res='url:%s size:%s\n' %(res['url'],len(res['text']))
f.write(parse_res)
if __name__ == '__main__':
# p=ProcessPoolExecutor()
p=ThreadPoolExecutor()
urls = [
'https://www.baidu.com',
'https://www.baidu.com',
'https://www.baidu.com',
'https://www.baidu.com',
'https://www.baidu.com',
'https://www.baidu.com',
] for url in urls:
# multiprocessing.pool_obj.apply_async(get_page,args=(url,),callback=parse_page)
p.submit(get_page, url).add_done_callback(parse_page)
p.shutdown()
print('主',os.getpid())

  3. map方法

 from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
import os,time,random
def task(n):
print('%s is running' %os.getpid())
time.sleep(2)
return n**2 if __name__ == '__main__':
p=ProcessPoolExecutor()
obj=p.map(task,range(10))
p.shutdown()
print('='*30)
print(list(obj))

3.补充:

单线程下串行十个任务效率不一定低,如果是计算型任务,效率不会低

同步异步指的是提交任务的方式

同步:提交任务(纯计算任务)后在原地等着  并不是阻塞。              等待不一定是发生了阻塞:计算时间过长也会等

因为gil锁,python的一个进程的多个线程不能实现并行,但是可以实现并发

如果你开的线程个数在机器的承受范围之内,开线程效率高,如果不行就需要用线程池

函数实现的协程:yield

单线程中提高效率:看情况再说协程,如果是计算型任务你开协程来回的切,反而降低了效率

协程不是真的存在

单线程不可能同时并行两个任务,但是可以出现并发效果
05-21 12:48