这段时间弄一个模型处理数据时因为运算量很大,导致模型整体效率很低,后来想到把数据分段,开多进程来同时处理可以大大降低时间,简单来说就是,本来一个数据我单独主程序需要处理花10min,然后我把这个数据分成10段,再分别开了10个进程单独处理其中一段,因为这些进程是并行运算的(会加大电脑CPU运算量),那么总共你的时间就只花了1min,就很赚了。
说干就干,先写一个简单的多进程代码。

简单的多进程代码

from multiprocessing import Process
import time
def function(a,b):#自定义的函数
    print(a,b)
    time.sleep(3)#这里睡眠3秒,
    print('相加结果=',a+b)

if __name__ == '__main__':
    for i in range(5):#开始5个进程
        p=Process(target=function,args=(i,i+1))
        p.start()#开始进程
    print('主进程')

注意!开始多进程的代码一定是放到主函数main中执行的,不然会报错,程序会无法识别哪个部分才是主进程。

关于Process函数说明,target是我们要让这个进程运行的目标函数,就是我们自己定义的函数function,然后这个函数我自己定义了两个参数a,b,所以后面args=(i,i+1)表示参数的传递,a=i,b=i+1。

然后再看函数中间睡眠了3秒,这里是5个进程,如果这5次操作是单线程处理,那么总共的时间就是15秒,这里因为是并行运算,总共只花了3秒左右,为啥叫左右呢,因为每个进程并不能保证同时开始同时结束,会存在一定的时间差异。

运行结果如下

sanic多进程加载gpu任务 多进程处理数据_数据


然后会注意到一个问题,开启多进程的代码在print(‘主进程’)之前,但是显示的内容告诉我们,print(‘主进程’)先运行了,为啥不是多进程全部运行结束才到这里呢?因为多进程开启可以理解为到后台慢慢执行任务去了,执行结束才回到主进程,所以导致了开启后主进程的代码print(‘主进程’)先运行的情况,那么我们肯定是希望得到所有多进程都运行结束才到print(‘主进程’)啊,因为等着前面多进程把数据给我们处理好呢,于是如下代码。

加了阻塞等待所有进程结束代码

from multiprocessing import Process
import time
def function(a,b):#自定义的函数
    print(a,b)
    time.sleep(3)#这里睡眠3秒,
    print('相加结果=',a+b)

if __name__ == '__main__':
    jobs=[]
    for i in range(5):#开始5个进程
        p=Process(target=function,args=(i,i+1))
        jobs.append(p)
        p.start()#开始进程
    for proc in jobs:
        proc.join()#利用阻塞等待所有进程结束才往下执行
    print('主进程')

运行结果

sanic多进程加载gpu任务 多进程处理数据_多线程_02


看吧,现在就好了,所有的进程运行结束,才继续执行主线程后面的操作。

现在又遇到一个问题,怎么把进程里处理的内容拿出来呢?进程从开始执行到结束都是作为一个独立的部分,你不能指望它返回函数运行的结果,于是我们可以利用共享变量的方法,把主线程的变量和多进程中的变量实现共享,这样就可以得到数据了。

获得多进程中运行处理的数据

from multiprocessing import Manager
from multiprocessing import Process
import time
def function(a,b,common_data):#自定义的函数
    print(a,b)
    time.sleep(3)#这里睡眠3秒,
    print('相加结果=',a+b)
    common_data.append(a+b)#将函数运算的结果添加

if __name__ == '__main__':
    jobs=[]
    common_data=Manager().list()#这里是声明一个列表的共享变量
    #common_data=Manager().dict()#声明一个字典的共享变量,以此类推其他数据类型
    for i in range(5):#开始5个进程
        p=Process(target=function,args=(i,i+1,common_data))#共享common_data这个变量
        jobs.append(p)
        p.start()#开始进程
    for proc in jobs:
        proc.join()#利用阻塞等待所有进程结束才往下执行
    print('主进程')
    print('多进程运算结果',common_data)

运行结果

sanic多进程加载gpu任务 多进程处理数据_python_03


如果有问题请及时指出,谢谢~