【问题标题】:How can I protect a logging object from the garbage collector in a multiprocessing process?如何在多处理过程中保护日志对象免受垃圾收集器的影响?
【发布时间】:2010-11-30 14:41:46
【问题描述】:

我使用 Python 的多处理模块 2.6 创建了几个工作进程。 在每个工作人员中,我使用标准日志记录模块(每个工作人员使用日志轮换和文件) 密切关注工人。我注意到几个小时后不再 事件被写入日志。该进程似乎没有崩溃并且仍然响应 通过我的队列命令。使用 lsof 我可以看到日志文件不再打开。 我怀疑日志对象可能被垃圾收集器杀死,如果是的话有办法吗 我可以标记它以保护它吗?

【问题讨论】:

  • 我真的怀疑 GC 与它有什么关系......

标签: python multithreading logging garbage-collection multiprocessing


【解决方案1】:

我同意@THC4k。这似乎不是 GC 问题。我会给你我的理由,如果我错了,我相信有人会拒绝我(如果是,请留下评论指出我的错误!)。

如果您使用 CPython,它主要使用引用计数,当引用计数变为零时,对象会立即销毁(从 2.0 开始,还提供了补充垃圾收集来处理循环引用的情况)。保留对日志对象的引用,它不会被销毁。

如果您使用的是 Jython 或 IronPython,则底层 VM 会执行垃圾收集。同样,保留一个引用,GC 不应该碰它。

无论哪种方式,您似乎都没有保留对您需要保持活动状态的对象的引用,或者您有其他错误。

【讨论】:

  • CPython 确实有一个标记和清除垃圾收集器。它使用引用计数作为性能改进,因此不必标记和扫描非循环数据结构。无论哪种方式,如果您不想收集某些东西,解决方案都是相同的,请保留对它的引用。
  • 我还没有找到问题所在,但据我所知,通过 lsof (htop) 报告的文件句柄丢失似乎是不正确的。我认为 htop/lsof 集成存在错误 :)
【解决方案2】:
http://docs.python.org/reference/datamodel.html#object.__del__

根据本文档,del() 方法在对象销毁时被调用,此时您可以创建对该对象的引用以防止它被收集。我不知道该怎么做,希望这能给你一些思考。

【讨论】:

    【解决方案3】:

    您可以在 fork() 之后立即运行 gc.collect() 以查看是否会导致日志关闭。但垃圾回收不可能在几个小时后才会生效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-29
      • 1970-01-01
      • 2017-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多