|
|
|
|
|
by ptx
775 days ago
|
|
Oh, I see. You want to avoid serializing the objects since they will be copied anyway with fork(), but the parent needs a way to refer to a particular object when talking to the child, so it needs to pass some kind of ID. You could also do it without pointers and ctypes by using e.g. an array index as the ID: inherited_objects = []
def ref(obj):
object_id = len(inherited_objects)
inherited_objects.append(obj)
return object_id
def deref(object_id):
return inherited_objects[object_id]
Although this part needs a small change as well, so that the object ID is assigned before forking: def parent():
bo1 = BigObject()
bo2 = BigObject()
refs = list(map(ref, [bo1, bo2]))
with mp.Pool(2) as pool:
result = pool.map(child, refs)
|
|
Yes, that is exactly and succintely the crux of the idea :-)
As you found out, you can rely on indices or keys in a global object to achieve the same result. The annoying part though is that you need to pre-provision these objets before the pool, and clean them after to avoid keeping references to them. That means some explicit boilerplate every time you use a pool.
The nice thing with the id() trick is that it's very unintrusive for the caller, as the reference count stays the same in the parent process, it is only increased in the child, unbeknownst to the parent.