使用具有多处理的上下文管理器有什么好处.经理?



在文档中,管理器与上下文管理器(即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 = MyManager()
maths = manager.Maths()
print(maths.add(4, 3))         # prints 7
print(maths.mul(7, 8))         # prints 56

但是这样做有什么好处(...)?

首先,您可以获得几乎所有上下文管理器的主要好处。 您为资源定义了明确定义的生存期。 它在打开with ...:块时分配和获取。 当块结束时(通过到达终点或因为引发异常)时,它会释放。 每当垃圾回收器处理它时,它仍然会被释放,但这不太重要,因为外部资源已经释放。

multiprocessing.Manager(这是一个返回SyncManager的函数,即使Manager看起来很像一个类)的情况下,资源是一个"服务器"进程,它保存状态和许多共享该状态的工作进程。

管理器

的 [使用上下文管理器的好处] 是什么?

如果您不使用上下文管理器并且没有在管理器上调用关闭,则"服务器"进程将继续运行,直到SyncManager__del__运行。 在某些情况下,这可能会在创建SyncManager的代码完成后不久发生(例如,如果它是在一个短函数中创建的,并且函数正常返回并且您使用的是CPython,那么引用计数系统可能会很快注意到对象已死并调用其__del__)。 在其他情况下,它可能需要更长的时间(如果引发异常并保留对管理器的引用,那么它将保持活动状态,直到处理该异常)。 在某些不好的情况下,它可能永远不会发生(如果SyncManager最终进入参考循环,那么它的__del__将阻止循环收集器收集它;或者你的进程可能会在调用__del__之前崩溃)。 在所有这些情况下,您都放弃了对清理SyncManager创建的额外 Python 进程的控制。 这些进程可能代表系统上的重要资源使用情况。 在非常糟糕的情况下,如果您在循环中创建SyncManager,则最终可能会创建许多同时存在并且很容易消耗大量资源的这些

如果不在上下文中使用它,则必须使用哪些步骤来确保正确关闭所有内容?

您必须自己实现上下文管理器协议,就像您在没有with的情况下使用的任何上下文管理器一样。 在纯Python中做这件事很棘手,同时仍然是正确的。 像这样:

manager = None
try:
manager = MyManager()
manager.__enter__()
# use it ...
except:
if manager is not None:
manager.__exit__(*exc_info())
else:
if manager is not None:
manager.__exit__(None, None, None)

startshutdown分别是__enter____exit__的别名。

相关内容

  • 没有找到相关文章

最新更新