python多任务如何提升效率
1.基本概念
并发:一个时间段内干多件事情(同时写文档,打游戏,聊天,1核交替执行,手先写再玩再聊) 并发是通过利用等待时间来提升速度,打游戏的等待时间去聊天,聊天的等待时间去写文档 并行:同一时刻干多件事情(同时听音乐,打游戏,看电影,3核同时运行,耳,手,眼) 并发是通过同时运行多任务的方式来提升速度 同步:各个任务不是独立运行的,任务之间有一定的交替顺序 异步:各个任务是独立运行的,一个任务的运行不影响另一个任务运行 线程:一个进程(任务)包含多个线程 进程:一个任务就是一个进程
2.python中提升效率的库
多进程:通过multiprocessing来实现(进程池) 多线程:通过threading来实现 协程:通过asyncio、genvent(不支持win)实现
3.多线程、多进程和协程比较
缺点: 多进程稳定,多线程不稳定,多线程如果一个子任务崩溃就会影响整个程序执行,多进程创建进程的代价大,会造成系统卡死。协程因为是异步执行,如果要提升效率需要使用支持异步的包。 适用情况: 多进程适合计算较大(利用较多CPU型)的程序。多线程和协程在处理有耗时操作的程序(I/O密集型)(文件读写,网络请求)时效率较高,但是协程是通过一个线程实现的。
4.python提高效率的最优解决
使用多进程和协程:multiprocessing+asyncio
5.三种方法的效率对比
第一次测试: 500000组数据,每组里面1000个浮点数,然后相乘。结果是多进程的确对计算量较大的程序效率提升明显,比多线程效率高了30多倍,比协程高了5倍。
测试代码
import threading import time from multiprocessing.dummy import Pool import asyncio import random def fun1(num_array): result=1 for i in num_array: result=result*i async def fun2(num_array): result=1 for i in num_array: result=result*i if __name__=='__main__': #生成数据 start_start=time.time() c=[] for i in range(1,500000): b=[] for j in range(1,1000): a=random.uniform(1,1000) b.append(a) c.append(b) # 多线程 start_threading=time.time() multithread=[] for i in c: one_thread=threading.Thread(target=fun1,args=(i,)) multithread.append(one_thread) for i in multithread: i.start() for j in multithread: j.join() print('多线程程序时间'+str(time.time()-start_threading)) #多进程(进程池) start_pool=time.time() pool=Pool(1000) pool.map(fun1,c) pool.close() pool.join() print('多进程程序时间'+str(time.time()-start_pool)) #协程 strat_asyncio = time.time() stasks = [] for i in c: task = fun2(i) # 创建任务 one_task = asyncio.ensure_future(task) # 形成任务列表 stasks.append(one_task) # 创建一个事件循环对象 loop = asyncio.get_event_loop() # 将任务列表封装到wait中,开始执行 loop.run_until_complete(asyncio.wait(stasks)) # 还可以绑定回调函数,在返回时调用 print('协程运行时间'+str(time.time() - strat_asyncio)) print('总的时间'+str(time.time()-start_start))
第二次测试: 每次写入一个1m大小的文件,写入5000次,3者时间几乎是差不多的。
测试代码
import asyncio import aiohttp import requests import threading import time from multiprocessing.dummy import Pool fp=open('1.txt','r') data=fp.read() fp=open('2.txt','w') def get_page1(num): fp.write(data) async def get_page2(url): fp.write(data) if __name__=='__main__': #生成数据 start_start=time.time() # 多线程 start_threading=time.time() multithread=[] for i in range(1,5000): one_thread=threading.Thread(target=get_page1,args=(i,)) multithread.append(one_thread) for i in multithread: i.start() for j in multithread: j.join() print('多线程程序时间'+str(time.time()-start_threading)) #多进程(进程池) start_pool=time.time() pool=Pool(500) pool.map(get_page1,range(1,5000)) pool.close() pool.join() print('多进程程序时间'+str(time.time()-start_pool)) #协程 strat_asyncio = time.time() stasks = [] for i in range(5000): task = get_page2(i) # 创建任务 one_task = asyncio.ensure_future(task) # 形成任务列表 stasks.append(one_task)
6.总结
多进程的效率还是很高的,但是开的进程多了以后对资源占用也大,之后学习一下多进程+协程的方式,达到低消耗,高效率的效果。