Shared Array not shared correctly in python multiprocessing

匿名 (未验证) 提交于 2019-12-03 02:31:01

问题:

I am experimenting multiprocessing in Python and tried to share an Array of strings among two processes. Here is my python code :

from multiprocessing import Process, Array, Value import ctypes  def f1(a, v):     for i, l in enumerate(['a', 'b', 'c']):         a[i] = l*3      v.value += 1      print "f1 : ", a[:], v.value  def f2(a,v):      v.value += 1      print "f2 : ", a[:], v.value  if __name__ == '__main__':     val = Value(ctypes.c_int, 0)     arr = Array(ctypes.c_char_p, 3)      print "Before :", arr[:], val.value      p = Process(target=f1, args=(arr, val))     p2 = Process(target=f2, args=(arr, val))      p.start()     p2.start()      p.join()     p2.join()      print "After : ", arr[:], val.value 

When I run the script I see that arr is correctly populated and available in f1() but not in f2(). Here is the result:

    % python /tmp/tests.py     Before : [None, None, None] 0     f1 :  ['aaa', 'bbb', 'ccc'] 1     f2 :  ['\x01', '\x11', '\x01'] 2     After :  ['\x01', '\x01', '\x01'] 2 

Did I overlooked something ?

Thanks in advance for your feedback. :)

回答1:

My guess is:

arr stores 3 pointers. f1() assigns them to memory addresses that have no meaning outside current process. f2() tries to access the meaningless addresses that contain junk at this point.

Assigning to values that have meaning in all processes seems to help:

from __future__ import print_function import ctypes import time from multiprocessing import Process, Array, Value  values = [(s*4).encode('ascii') for s in 'abc']  def f1(a, v):     for i, s in enumerate(values):         a[i] = s      v.value += 1      print("f1 : ", a[:], v.value)  def f2(a,v):     v.value += 1     print("f2 : ", a[:], v.value)  def main():     val = Value(ctypes.c_int, 0)     arr = Array(ctypes.c_char_p, 3)      print("Before :", arr[:], val.value)      p = Process(target=f1, args=(arr, val))     p2 = Process(target=f2, args=(arr, val))      p.start()     p2.start()      p.join()     p2.join()      print("After : ", arr[:], val.value)  if __name__ == '__main__':     main() 

Output

Before : [None, None, None] 0 f1 :  ['aaaa', 'bbbb', 'cccc'] 1 f2 :  ['aaaa', 'bbbb', 'cccc'] 2 After :  ['aaaa', 'bbbb', 'cccc'] 2 


回答2:

I don't have a solution, but I can add more hints. I've stripped the script to pinpoint the problem. It looks to me that the problem is in the l * 3 operation. I don't know why, but moving the l * 3 operation in the enumerator works as expected:

from multiprocessing import Process, Array                                    import ctypes                                                                   def f1(a):                                                                    #    for i, l in enumerate(['a', 'b', 'c']):                                  #        a[i] = (l * 3)                                                           for i, l in enumerate(['a' * 3, 'b' * 3, 'c' * 3]):                               a[i] = l                                                                   print "f1 : ", map(id, a), a[:]                                             if __name__ == '__main__':                                                        arr = Array(ctypes.c_char_p, 3)                                                print "Before :", map(id, arr), arr[:]                                        p = Process(target=f1, args=(arr, ))                                          p.start()                                                                     p.join()                                                                      print "After : ", map(id, arr), arr[:]                                    

Result:

Before : [3077673516L, 3077673516L, 3077673516L] [None, None, None] f1 :  [3073497784L, 3073497784L, 3073497784L] ['aaa', 'bbb', 'ccc'] After :  [3073497784L, 3073497784L, 3073497784L] ['aaa', 'bbb', 'ccc'] 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!