python-多进程Value、Array应⽤记录
在代码优化的过程中,碰到了这样⼀个问题:⼀个进程中我定义了⼏个全局变量,然后我⼜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
python 定义数组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]
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论