在the documentation中,Manager与上下文管理器(即with
)一起使用,如下所示:
from multiprocessing.managers import BaseManager
class MathsClass:
def add(self, x, y):
return x + y
def mul(self, x, y):
return x * y
class MyManager(BaseManager):
pass
MyManager.register('Maths', MathsClass)
if __name__ == '__main__':
with MyManager() as manager:
maths = manager.Maths()
print(maths.add(4, 3)) # prints 7
print(maths.mul(7, 8)) # prints 56
但是除了名称空间之外,这有什么好处呢?对于打开文件流,好处非常明显,因为您不必手动.close()
连接,但是对于Manager来说是什么呢?如果不在上下文中使用它,那么您必须使用哪些步骤来确保所有内容都已正确关闭?你知道吗
简言之,使用上述方法的好处是什么
manager = MyManager()
maths = manager.Maths()
print(maths.add(4, 3)) # prints 7
print(maths.mul(7, 8)) # prints 56
首先,您可以从几乎所有上下文管理器中获得主要好处。您有一个明确定义的资源生存期。它是在
with ...:
块打开时分配和获取的。当块结束时释放它(通过到达结尾或引发异常)。每当垃圾回收器找到它时,它仍然会被释放,但是由于外部资源已经被释放,所以这就不那么重要了。你知道吗在
multiprocessing.Manager
(这是一个返回SyncManager
的函数,尽管Manager
看起来很像一个类)的情况下,资源是一个保存状态的“服务器”进程和许多共享该状态的工作进程。你知道吗如果不使用上下文管理器并且不在管理器上调用shutdown,那么“服务器”进程将继续运行,直到
SyncManager
的__del__
运行为止。在某些情况下,这可能发生在创建SyncManager
的代码完成后不久(例如,如果它是在一个短函数中创建的,并且函数返回正常,并且您正在使用CPython,那么引用计数系统可能会很快注意到对象已死亡,并调用其__del__
)。在其他情况下,可能需要更长的时间(如果引发异常并保留对管理器的引用,则在处理该异常之前,它将保持活动状态)。在某些不好的情况下,它可能根本不会发生(如果SyncManager
在引用循环中结束,那么它的__del__
将阻止循环收集器收集它;或者在调用__del__
之前,您的进程可能会崩溃)。在所有这些情况下,您将放弃对清理SyncManager
创建的额外Python进程的控制。这些进程可能表示系统上的非平凡资源使用情况。在非常糟糕的情况下,如果您在一个循环中创建SyncManager
,那么最终可能会创建许多同时存在的循环,并且很容易消耗大量资源。你知道吗您必须自己实现上下文管理器协议,就像您在没有
with
的情况下使用的任何上下文管理器一样。在纯Python中这样做是很困难的,但仍然是正确的。比如:start
和shutdown
也分别是__enter__
和__exit__
的别名。你知道吗相关问题 更多 >
编程相关推荐