Python的关闭程序记录在哪里? [英] Where is Python's shutdown procedure documented?

查看:104
本文介绍了Python的关闭程序记录在哪里?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

CPython的行为很奇怪,它在关闭过程中将模块设置为None.这会关闭我编写的一些多线程代码期间的错误日志记录.

CPython has a strange behaviour where it sets modules to None during shutdown. This screws up error logging during shutdown of some multithreading code I've written.

我找不到有关此行为的任何文档.在传递 PEP 432 :

I can't find any documentation of this behaviour. It's mentioned in passing in PEP 432:

[...]大大减少了将经历模块全局设置为无"行为的模块数量,该行为用于故意中断周期并尝试干净地释放更多的外部资源.

[...] significantly reducing the number of modules that will experience the "module globals set to None" behaviour that is used to deliberate break cycles and attempt to releases more external resources cleanly.

关于此行为,有 SO问题我还在python-上找到了相关线程dev 相关的CPython错误:

I've also found a related thread on python-dev and a related CPython bug:

此修补程序不会更改模块的行为 对象尽快清除其全局字典 他们被释放了.

This patch does not change the behavior of module objects clearing their globals dictionary as soon as they are deallocated.

此行为记录在哪里?是特定于Python 2的吗?

Where is this behaviour documented? Is it Python 2 specific?

推荐答案

的行为没有得到充分的记录,并且在所有版本的Python中都存在,大约1.5位数,直到 Python 3.4 :

The behaviour is not well documented, and is present in all versions of Python from about 1.5-ish until Python 3.4:

作为此更改的一部分,在大多数情况下,在解释器关闭期间,不再将模块全局变量强制设置为None,而是依靠循环垃圾收集器的正常操作.

As part of this change, module globals are no longer forcibly set to None during interpreter shutdown in most cases, instead relying on the normal operation of the cyclic garbage collector.

有关此行为的唯一文档是 moduleobject.c源代码 :

The only documentation for the behaviour is the moduleobject.c source code:

/* To make the execution order of destructors for global
   objects a bit more predictable, we first zap all objects
   whose name starts with a single underscore, before we clear
   the entire dictionary.  We zap them by replacing them with
   None, rather than deleting them from the dictionary, to
   avoid rehashing the dictionary (to some extent). */

请注意,将值设置为None是一种优化;另一种选择是从映射中删除名称,这将导致不同的错误(尝试从__del__处理程序使用全局变量时,使用NameError例外而不是AttributeError).

Note that setting the values to None is an optimisation; the alternative would be to delete names from the mapping, which would lead to different errors (NameError exceptions rather than AttributeErrors when trying to use globals from a __del__ handler).

正如您在邮件列表中发现的那样,此行为早于循环垃圾收集器.它是在1998年添加的,而循环垃圾收集器是

As you found out on the mailinglist, the behaviour predates the cyclic garbage collector; it was added in 1998, while the cyclic garbage collector was added in 2000. Since function objects always reference the module __dict__ all function objects in a module involve circular references, which is why the __dict__ needed clearing before GC came into play.

即使添加了循环GC,它也会保留在原位,因为循环中可能包含使用__del__方法的对象.这些否则就不会被垃圾收集,并且清理模块字典至少会从此类循环中卸下模块__dict__.不这样做将使该模块的 all 个引用全局变量保持活动状态.

It was kept in place even when cyclic GC was added, because there might be objects with __del__ methods involved in cycles. These aren't otherwise garbage-collectable, and cleaning out the module dictionary would at least remove the module __dict__ from such cycles. Not doing that would keep all referenced globals of that module alive.

PEP 442 所做的更改现在使垃圾收集器可以清除循环引用带有提供__del__终结器的对象,从而在大多数情况下无需清除模块__dict__ .代码仍然是仍然存在,但这仅在__dict__属性被触发时才会触发即使将sys.modules的内容移至弱引用并在解释器关闭时启动GC收集运行,它仍然有效.模块终结器只需减少其引用计数即可.

The changes made for PEP 442 now make it possible for the garbage collector to clear cyclic references with objects that provide a __del__ finalizer, removing the need to clear the module __dict__ for most cases. The code is still there but this is only triggered if the __dict__ attribute is still alive even after moving the contents of sys.modules to weak references and starting a GC collection run when the interpreter is shutting down; the module finalizer simply decrements their reference count.

这篇关于Python的关闭程序记录在哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆