Search code examples
pythonpython-multiprocessing

How to work with a multiprocessing.Manager() Array in python


I'm launching a worker process using Python's multiprocessing. I need to be able to update an array in the subprocess that can be seen in the parent process. I use multiprocessing.Manager() to accomplish that.

a = multiprocessing.Manager().Array('f', [0,0])
a
<ArrayProxy object, typeid 'Array' at 0x7f4e2b4eeda0>

a.value
Traceback (most recent call last):
  File "<blender_console>", line 1, in <module>
AttributeError: 'ArrayProxy' object has no attribute 'value'

When I create a Value('f', 0.0) I can operate on it this way. When I look at dir(a) I don't see any obvious functions or attributes to call, and the documentation in python is really fuzzy about this point.


Solution

  • a is a proxy object

    <ArrayProxy object, typeid 'Array' at 0x7f4e2b4eeda0>
    

    A proxy is an object which refers to a shared object which lives (presumably) in a different process. The shared object is said to be the referent of the proxy.

    The relationship between proxy object and the real object as following shown, in multiprocessing/managers.py

    SyncManager.register('Value', Value, ValueProxy)
    SyncManager.register('Array', Array, ArrayProxy)
    

    And we see the supported operators of ArrayProxy

    ArrayProxy = MakeProxyType('ArrayProxy', (
        '__len__', '__getitem__', '__setitem__', '__getslice__', '__setslice__'
        ))                  # XXX __getslice__ and __setslice__ unneeded in Py3.0
    

    The Array is actually array.array(...)

    Value(typecode, value) is different from Array

    Create an object with a writable value attribute and return a proxy for it.

    class ValueProxy(BaseProxy):
        _exposed_ = ('get', 'set')
        def get(self):
            return self._callmethod('get')
        def set(self, value):
            return self._callmethod('set', (value,))
        value = property(get, set)