Python 多进程 ValueArray应用记录
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 多进程 ValueArray应用记录相关的知识,希望对你有一定的参考价值。
在代码优化的过程中,碰到了这样一个问题:一个进程中我定义了几个全局变量,然后我又Process了几个子进程,子进程中是否可以各自对全局变量进行修改?最后全局变量会取哪个值呢?
经过一番尝试以后得到结果:
子进程继承父进程的全局变量,而且是以复制的形式完成,所以子进程修改后的全局变量只对自己和自己的子进程有影响。
父子进程不共享这些全局变量,也就是说:父进程中对全局变量的修改不影响子进程中的全局变量,同理,子进程也不影响父进程的。
为了实现父子进程的通信,在网上经过了一番翻找以后,找到了 Value和Array 方法
Value函数返回一个shared memory包装类,其中包含一个ctypes对象
一般 整数用 i, 字符用 c,浮点数用 d 就可以了
Array函数返回一个shared memory包装类,其中包含一个数组,字符串需要用 Array 来传递
- @args shared memory 中包含的值
- @lock 默认值是True:创建一个新的lock来控制对value的访问。该参数也可以是 multiprocessing.Lock 或 multiprocessing.RLock 对像,用来控制对value的访问
================================================================================================================================
案例一:
def worker(num, mystr, arr): num.value *= 2 mystr.value = "ok" for i in range(len(arr)): arr[i] = arr[i] * (-1) + 1.5 def dump_vars(num, mystr, arr): print ‘num: ‘, num.value print ‘str: ‘, mystr[:] print ‘arr: ‘, arr[:] if __name__==‘__main__‘: num = Value(‘i‘, 5) mystr = Array(‘c‘, ‘just for test‘) arr = Array(‘d‘, [1.0, 1.5, -2.0]) dir(str) print ‘init value‘ dump_vars(num, mystr, arr) ps = [Process(target=worker, args=(num, mystr, arr)) for x in range(3)] for p in ps: p.start() for p in ps: p.join() print print ‘after all workers finished‘ dump_vars(num, mystr, arr)
#结果: init value num: 5 str: just for test arr: [1.0, 1.5, -2.0] after all workers finished num: 40 str: ok
多次测试我发现,在共享字符串的时候,在主进程中的初始化决定了这个字符串的长度,
创建后字符串的长度固定不变,相当于把这个字符串所在的地址复制给一个指针,并且在字符串的首地址记录了自身的长度,
在以后读取这个值的时候就会去读取那一段固定长度的内容,而不管现在的新内容长度是多少,举个例子:
比如我们在主进程初始化一段字符串 "abcde",一旦初始化,长度就固定了,现在长度是5,然后我们在其他进程赋值,我们尝试赋值为
"abcdefg",此时执行会报错,因为长度超标了,我们在赋值为
"yes",最后输出结果为
"yes&efg"(此处的&是代表一个不可显示的字符,不同的环境下显示不同,有可能显示空格,有可能显示null)。也就是说长短都不行,必须和初始化字符串等长。
于是得出这样一个结论,如果你要共享一个字符串,那么在子进程中赋值时必须赋值长度相当的字符串。建议在子进程中可以先检查字符串长度,然后在根据需要拼接指定长度的字符串
案例二:
from multiprocessing import Process, Value, Array def f(n, a): n.value = n.value + 1 for i in range(len(a)): a[i] = a[i] * 10 if __name__ == ‘__main__‘: num = Value(‘i‘, 1) arr = Array(‘i‘, range(10)) p = Process(target=f, args=(num, arr)) p.start() p.join() print(num.value) print(arr[:]) p2 = Process(target=f, args=(num, arr)) p2.start() p2.join() print(num.value) print(arr[:]) # the output is : # 2 # [0, 10, 20, 30, 40, 50, 60, 70, 80, 90] # 3 # [0, 100, 200, 300, 400, 500, 600, 700, 800, 900]
以上是关于Python 多进程 ValueArray应用记录的主要内容,如果未能解决你的问题,请参考以下文章
Python-logging详解(彩色日志扩展,多进程安全等)