进程池
进程池:一个池子,里边有固定数量的进程。这些进程一直处于待命状态,一旦有任务来,马上就有进程去处理。
因为在实际业务中,任务量是有多有少的,如果任务量特别的多,不可能要开对应那么多的进程数
开启那么多进程首先就需要消耗大量的时间让操作系统来为你管理它。其次还需要消耗大量时间让
cpu帮你调度它。
进程池还会帮程序员去管理池中的进程。
from multiprocessing import Pool
p = Pool(os.cpu_count() + 1)
进程池有三个方法:
map(func,iterable)
func:进程池中的进程执行的任务函数
iterable: 可迭代对象,是把可迭代对象中的每个元素依次传给任务函数当参数
apply(func,args=()): 同步的效率,也就是说池中的进程一个一个的去执行任务
func:进程池中的进程执行的任务函数
args: 可迭代对象型的参数,是传给任务函数的参数
同步处理任务时,不需要close和join
同步处理任务时,进程池中的所有进程是普通进程(主进程需要等待其执行结束)
apply_async(func,args=(),callback=None): 异步的效率,也就是说池中的进程一次性都去执行任务
func:进程池中的进程执行的任务函数
args: 可迭代对象型的参数,是传给任务函数的参数
同步:
from multiprocessing import Pool
import time
def func(i):
time.sleep(0.5)
print(i+1)
if __name__ == '__main__':
p = Pool()
for i in range(100):
p.apply(func,args=(i,))
同步处理这100个任务,同步是指,哪怕我进程中有5个进程,也依旧是1个进程1个进程的去执行任务
异步:
from multiprocessing import Pool
import time
def func(i):
time.sleep(0.5)
print(i+1)
if __name__ == '__main__':
p = Pool(5)
for i in range(100):
p.apply_async(func,args=(i,))
p.close()
p.join()
异步处理这100个任务,异步是指,进程中有5个进程,一下就处理5个任务,
接下来哪个进程处理完任务了,就马上去接收下一个任务
同步异步处理任务效率对比
同步:
from multiprocessing import Pool
import time
def func(i):
print(i+1)
if __name__ == '__main__':
p = Pool()
start = time.time()
for i in range(100):
p.apply(func,args=(i,))
print(time.time()-start)
异步:
from multiprocessing import Pool
import time
def func(i):
print(i+1)
if __name__ == '__main__':
p = Pool(5)
start = time.time()
for i in range(100):
p.apply_async(func,args=(i,))
p.close()
p.join()
print(time.time()-start)
# 同步异步效率比
from multiprocessing import Pool
import time
import requests
def func(url):
res = requests.get(url)
print(res.text)
if res.status_code ==200:
return "ok"
if __name__ == '__main__':
p = Pool(5)
l = ['https://www.baidu.com',
'http://www.jd.com',
'http://www.taobao.com',
'http://www.mi.com',
'http://www.cnblogs.com',
'https://www.bilibili.com',
]
start = time.time()
for i in l:
p.apply(func, args=(i,))
a = time.time()-start
start = time.time()
for i in l:
p.apply_async(func, args=(i,))
p.close()
p.join()
b = time.time() - start
print(a,b)
from multiprocessing import Pool
def func(n):
n+=1
print(n)
return n #主进程返回值
if __name__ == '__main__':
p = Pool(5)
ret =p.map(func,[i for i in range(100)])
p.close()
p.join()
print("主进程中map返回的值是",ret )
# 进程池和多进程的效率比
from multiprocessing import Pool,Process
import time
import os
def func(n):
print(n+1)
if __name__ == '__main__':
p = Pool(os.cpu_count()+1)
start = time.time()
p.map(func,[i for i in range(100)])
p.close() # 指不允许在向进程池中添加任务
p.join() # 等待进程池中所有进程执行完所有任务
print('进程池做任务的效率:', time.time() - start)
start = time.time()
lst = []
for i in range(100):
p1 = Process(target=func,args=(i,))
p1.start()
lst.append(p1)
[p1.join() for p1 in lst]
print("多进程做任务的效率:",time.time() - start)
callback: 回调函数,就是说每当进程池中有进程处理完任务了,返回的结果可以交给回调函数,由回调函数进行进一步的处理,回调函数只有异步才有,同步是没有的
异步处理任务时,进程池中的所有进程是守护进程(主进程代码执行完毕守护进程就结束)
异步处理任务时,必须要加上close和join
回调函数的使用:
进程的任务函数的返回值,被当成回调函数的形参接收到,以此进行进一步的处理操作
回调函数是由主进程调用的,而不是子进程,子进程只负责把结果传递给回调函数
from multiprocessing import Pool
import requests
import os
def func(url):
res = requests.get(url)
print("子进程的pid",os.getpid())
# print(res.text)
if res.status_code == 200:
return url,res.text
def call_back(sta):
url,text = sta
print("回调函数的pid",os.getpid())
with open('a.txt','a',encoding='utf-8') as f:
f.write(url + text)
# print('回调函数中!', url)
if __name__ == '__main__':
p = Pool(5)
l = ['https://www.baidu.com',
'http://www.jd.com',
'http://www.taobao.com',
'http://www.mi.com',
'http://www.cnblogs.com',
'https://www.bilibili.com',
]
print("主进程的pid",os.getpid())
for i in l:
p.apply_async(func, args=(i,),callback=call_back)
p.close()
p.join()