Python3 多进程multiprocessing 编程之共享数据使用 与注意事项

目前处理了大概几十万个数据的计算,然后再刷新数据,耗时很严重,使用起来什么卡顿,这里学习使用一下python的多进程编程。

python由于有着GIL全局解释锁,多线程的实际效果并不是很明显,尤其是在计算量比较大的情况,毕竟python也不是为计算而设计的。

模块

这里使用的是python的多进程编程模块:multiprocessing,使用起来还是比较方便的。

共享内存

共享内存则是为进程使用的,主要有Value,Array,Manager三个可以使用。

1. Value和Array的使用类似,但是Value是创建一个变量大小的共享内存,而Array则是创建一个数组大小的共享内存。如下:

from multiprocessing import Process, Array,Value

money = Value('i',10)    #这个是创建一个int类型的共享内存变量
money = Array('l', 10)   #这个是创建一个long int类型的数组共享内存

Value:细节暂时不讲

Array:这里讲一个保存和读取python字符串的方法。本来是可以使用下面的Manager的,但是不知道为什么Manager一定义就会弹框报错.

字符串处理:

#首先创建一个字符数组并将数据写入:
sysparam = "hello world"

testArray = Array('u', 500) #创建一个共享数组
for i in range(len(sysparam)):    #遍历写值
   testArray[i] = sysparam[i]

testArray[i+1] = '$'            #添加一个结束标志,这里得是字符串中不可能存在的才行



#另外一边进行读取:
strPath = ""
for i in range(0,500):
    if argslist[i] =='$':
        break
    else:
        strPath += argslist[i]

 

2.Manager

这个共享内存可以创建python的一些专属类型,dict,list queue。使用更加方便,但是据说速度好像比上面的慢一些,具体我没有进行测试了。

from multiprocessing import Process,Manager
import os,time
def f(l):
    l.append("123")

if __name__ == '__main__':
    manager = Manager()
    lo= manager.list()
    lo.append(2)
    p = Process(target=f,args=(lo,))
    p.start()
   
    print(lo)
    time.sleep(0.1)
    print(lo)
    

简单测试例子

from multiprocessing import Process, Array

def f(a,b):
    a[1] = 3
    b[1] = 4

if __name__ == '__main__':
    arr = Array('l', 10)
    arr1 = Array('d', 10)
    p = Process(target=f, args=(arr,arr1))
    p.start()
    p.join()

    print(arr[1],arr1[1])

打印反馈为:

3 4.0

这里是等待p线程执行结束(join)才进行打印,如果删除p.join()语句,则不会立刻进行赋值为3 和4.0的。

----------------------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------------------

注意事项 

Array与list的交互

array共享变量赋值到list:

arrayvar = Array('l',10)
list = list(arrayvar)

list到array:

arrayvar = Array('l',10)
arrayvar = list #大小必须一样
arrayvar[1:2] = [1] #部分赋值大小也要一样

Pyinstaller的陷阱

这里最坑的就是打包之后,调用Process()来创建其他进程,最后竟然再次打开了自己?懵逼啊、

这里多谢:https://blog.csdn.net/xiong_big/article/details/54614231+https://github.com/pyinstaller/pyinstaller/wiki/Recipe-Multiprocessing

有坑就得查,谢谢大佬帮我填坑。

只要添加这么一个freeze_support()就OK了,如果你还不行?管我什么事,我已经开心地前进了~

if __name__ == '__main__':
    freeze_support()    #from multiprocessing

你可能感兴趣的:(python)