Josh Rosenberg <shadowranger+pyt...@gmail.com> added the comment:

Reading the docs, I'd definitely expect multiprocessing.Manager().Value to obey 
the same interface as multiprocessing.Value. The SyncManager docs say:

> Its methods create and return Proxy Objects for a number of commonly used 
> data types to be synchronized across processes.

It does also say (under the linked definition for Proxy Objects):

> A proxy object has methods which invoke corresponding methods of its referent 
> (although not every method of the referent will necessarily be available 
> through the proxy).

which implies the proxy might be more limited, but in fact the proxy is 
wrapping a completely different underlying class, 
multiprocessing.managers.Value (that has nothing to do with the class you'd get 
from calling multiprocessing.Value or multiprocessing.sharedctypes.Value).

It looks like there was, at some point, an attempt to make certain interfaces 
match; multiprocessing.managers.Value's initializer has a prototype of:

def __init__(self, typecode, value, lock=True):

(documented prototype excludes the lock argument), but AFAICT, lock is 
completely ignored, and typecode is stored as _typecode on the underlying 
Value, but otherwise ignored; the multiprocessing.managers.ValueProxy object 
returned by manager.Value() doesn't expose it (except insofar as you can call 
._getvalue() on it to retrieve a copy of the underlying Value), and even if you 
get the unwrapped object, all _typecode does is change the repr; it's not used 
anywhere else.

It seems like SyncManager.Value is just the worst of all possible worlds; it 
has a prototype that (roughly) matches 
multiprocessing.Value/multiprocessing.sharedctypes.Value, and the limited 
documentation implies it serves the same function, but:

1. It effectively ignores every argument aside from value (which is the second 
argument, so you're stuck passing the first argument even though nothing uses 
it)
2. It doesn't actually use ctypes to achieve efficient storage/IPC 
communication (updating value involves pickling it, not just sending the raw 
data of a C array/struct)
3. It doesn't provide any of the interface of the other Value, so you can't use 
get_lock (or use a with statement to lock it, or manually call acquire or 
release) or get_obj.

I'm not sure what to do about it though; the manager version of Value is much 
more flexible, and I'm sure there is existing code that takes advantage of 
that, so we can't rewrite to make it ctypes backed. The 
multiprocessing.managers code is too new/complex for me to determine if any 
easy solution exists to expand multiprocessing.managers.ValueProxy to support 
context management/get_lock/get_obj to match the behavior of the class returned 
by multiprocessing.Value/multiprocessing.sharedctypes.Value, but it seems like, 
if we're going to let the docs imply a relationship, we ought to at least try 
to make the API of the two classes roughly match.

----------
nosy: +josh.r

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue35786>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to