如何在多处理进程中保护日志记录对象免受垃圾收集器的影响?
我使用 Python 的多处理模块 2.6 创建了几个工作进程。 在每个工作人员中,我使用标准日志记录模块(每个工作人员具有日志轮换和文件) 密切关注工人。我注意到几个小时后就没有了 事件被写入日志。该进程似乎没有崩溃并且仍然响应 通过我的队列发送命令。使用 lsof 我可以看到日志文件不再打开。 我怀疑日志对象可能被垃圾收集器杀死,如果是这样有什么办法 我可以标记它以保护它吗?
I create a couple of worker processes using Python's Multiprocessing module 2.6.
In each worker I use the standard logging module (with log rotation and file per worker)
to keep an eye on the worker. I've noticed that after a couple of hours that no more
events are written to the log. The process doesn't appear to crash and still responds
to commands via my queue. Using lsof I can see that the log file is no longer open.
I suspect the log object may be killed by the garbage collector, if so is there a way
that I can mark it to protect it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我同意@THC4k。这看起来不像 GC 问题。我会给你我的理由,我相信如果我错了,有人会投票反对我(如果是这样,请留下评论指出我的错误!)。
如果您使用 CPython,它主要使用引用计数,当引用计数为零时,对象会立即销毁(从 2.0 开始,还提供补充垃圾收集来处理循环引用的情况)。保留对日志对象的引用,它不会被破坏。
如果您使用 Jython 或 IronPython,则底层 VM 会执行垃圾收集。再次强调,保留一个引用,GC 不应该碰它。
无论哪种方式,似乎要么您没有保留对需要保持活动状态的对象的引用,要么您有其他错误。
I agree with @THC4k. This doesn't seem like a GC issue. I'll give you my reasons why, and I'm sure somebody will vote me down if I'm wrong (if so, please leave a comment pointing out my error!).
If you're using CPython, it primarily uses reference counting, and objects are destroyed immediately when the ref count goes to zero (since 2.0, supplemental garbage collection is also provided to handle the case of circular references). Keep a reference to your log object and it won't be destroyed.
If you're using Jython or IronPython, the underlying VM does the garbage collection. Again, keep a reference and the GC shouldn't touch it.
Either way, it seems that either you're not keeping a reference to an object you need to keep alive, or you have some other error.
根据本文档,在对象销毁时调用 del() 方法,此时您可以创建对该对象的引用以防止它被收集。我不确定如何做到这一点,希望这能给您一些思考。
According to this documentation the del() method is called on object destruction and you can at this point create a reference to the object to prevent it from being collected. I am not sure how to do this, hopefully this gives you some food for thought.
您可以在 fork() 之后立即运行 gc.collect() 来查看是否会导致日志关闭。但垃圾收集不太可能在几个小时后才生效。
You could run
gc.collect()
immediately after fork() to see if that causes the log to be closed. But it's not likely garbage collection would take effect only after a few hours.