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.总结

多进程的效率还是很高的,但是开的进程多了以后对资源占用也大,之后学习一下多进程+协程的方式,达到低消耗,高效率的效果。