python多进程multiprocessing
Python中的线程手全局锁的影响,线程受限于某个cpu上,但是呢,多进程模式,不手此影响。多线程,省资源。多进程有点浪费资源,但是能利用上多核的性能。
记录一下,python中的多进程使用方式。另外一种多进程方式concurrent的库。
资料
- https://www.cnblogs.com/kaituorensheng/p/4465768.html
- https://www.cnblogs.com/haitaoli/p/9837697.html
- https://blog.csdn.net/mdjxy63/article/details/78354368
示例
多进程下载
对于标记的核心代码,解释如下,进程数,根据自己电脑的cpu的情况而定,不能太多,因为进程切换也需要耗时间的。重要:进程池,定义n个进程,但是,实际上,可以比它多,也可以比它少。
举例:如下,定义了4个进程,但是,pool.apply_async处,就调用1次,也是允许的。这样,最终,只会有一个进程。如果超过了它,比如n个进程,那么每次任务结束的时候,进程会执行新的任务。
下面seg_down,实际上是因为每次下载的任务太小了,故封装成一个大一点的任务量。这样,workers的变量也会少一点。
#coding=utf-8
import requests
from time import sleep
import multiprocessing as mp
import sys
"""
带有失败重试的下载功能代码
"""
def get_dipian(uid):
for i in range(10):
try:
resp = requests.get(url,headers=headers,stream=True)
break
except:
print('网络可能超时 id -- %s'%uid )
sleep(i)
if i == 9:
print('当前任务反复获取不到,被忽略 id -- %s'%uid)
return False
return resp.status_code == 200
"""
仅仅是合并一下任务,避免任务太多
"""
def seg_down(k):
result = []
for i in range(k*10000,min((k+1)*10000,pow(16,5))):
uid = '%05x'.upper()%i
if get_dipian(uid):
result.append(uid)
print(uid)
print('当前进度:%d 已完成'%(k))
return result
"""
多进程的方式,提高下载的并发速度
"""
def main():
result = []
assert len(sys.argv) == 3
start_n = sys.argv[1]
end_n = sys.argv[2]
assert start_n.isnumeric()
assert end_n.isnumeric()
start_n = int(start_n)
end_n = int(end_n)
# 多进程的核心代码
pool = mp.Pool(4)
workers = [pool.apply_async(seg_down,[k]) for k in range(start_n,end_n)]
pool.close()
pool.join()
result = [worker.get() for worker in workers]
with open('dipian_ids_%s.txt'%image_day,'a') as fo:
fo.write('\n'.join(['%s'%x for x in result]))
if __name__ == '__main__':
main()