有三个可能是重复的问题(但过于具体):
回答这个问题可以回答其他三个问题。希望我表述清楚:
一旦我在由多进程创建的某个进程中创建了一个对象:
- 我如何将对该对象的引用传递给另一个进程?
- (不太重要)当我持有一个引用时,如何确保该进程不会死亡?
示例1(已解决)
from concurrent.futures import *
def f(v):
return lambda: v * v
if __name__ == '__main__':
with ThreadPoolExecutor(1) as e: # works with ThreadPoolExecutor
l = list(e.map(f, [1,2,3,4]))
print([g() for g in l]) # [1, 4, 9, 16]
示例2
假设f
返回一个具有可变状态的对象。应该可以从其他进程访问此相同的对象。
示例3
我有一个具有打开文件和锁定的对象-如何授权其他进程访问?
提醒
我不希望出现特定错误,也不需要针对此特定用例的解决方案。解决方案应足够通用,以便在进程之间共享不可移动的对象。这些对象可能在任何进程中创建。也可以是使所有对象可移动并保留其标识的解决方案。
欢迎任何提示,任何部分解决方案或指向如何实现解决方案的代码片段都有价值。因此,我们可以一起创建解决方案。
这里是一个尝试解决这个问题,但没有使用多处理:https://github.com/niccokunzmann/pynet/blob/master/documentation/done/tools.rst
问题
你想让其他进程如何处理引用?
可以将引用传递给使用multiprocessing(重复3次)创建的任何其他进程。可以访问属性,调用引用。访问的属性可能是代理,也可能不是。
仅使用代理有什么问题?
也许没有问题,但有挑战。我的印象是代理有一个管理器,而管理器有自己的进程,因此无法序列化并传输不可序列化的对象(使用StacklessPython / fork部分解决)。此外,存在特殊对象的代理-难以但不是不可能为所有对象构建代理(可解决)。
解决方案?-代理+管理器?
Eric Urban表明序列化不是问题。真正的挑战在于示例2&3:状态的同步。我的解决方案想法是为管理器创建一个特殊的代理类。这个代理类
- 为不可序列化的对象提供构造函数
- 获取可序列化对象并将其传输到管理器进程。
- (问题)根据1,不可序列化的对象必须在管理器进程中创建。
multiprocessing.manager.BaseManager
的子类,然后调用 YourManager.register(YourClass)。这对于每个类都应该有效。而且它确实不会妨碍你,因为通常你知道哪些对象必须在进程之间共享,哪些不必共享。 - Kritzefitz