Python 带有守护进程线程的单例垃圾收集器
我已经实现了一个作为单例的记录器,其中所有消息都进入一个队列,守护进程线程从队列中收集这些消息并打印它们。 我使用守护进程线程的原因是,我不必在完成日志程序(或应用程序退出)后显式关闭它。 我希望在应用程序关闭时,一旦记录器被(垃圾收集器)删除,那么Python 带有守护进程线程的单例垃圾收集器,python,multithreading,garbage-collection,singleton,daemon,Python,Multithreading,Garbage Collection,Singleton,Daemon,我已经实现了一个作为单例的记录器,其中所有消息都进入一个队列,守护进程线程从队列中收集这些消息并打印它们。 我使用守护进程线程的原因是,我不必在完成日志程序(或应用程序退出)后显式关闭它。 我希望在应用程序关闭时,一旦记录器被(垃圾收集器)删除,那么\uuu del\uu方法将运行并在之后进行清理。我很惊讶事实并非如此 当我将线程更改为非守护进程时,它工作得很好(显然,我必须进行一些其他更改,以便应用程序退出)。我想知道我是否做错了什么,或者这只是一个糟糕的做法 这里附上了代码:(我建议\uu
\uuu del\uu
方法将运行并在之后进行清理。我很惊讶事实并非如此
当我将线程更改为非守护进程时,它工作得很好(显然,我必须进行一些其他更改,以便应用程序退出)。我想知道我是否做错了什么,或者这只是一个糟糕的做法
这里附上了代码:(我建议\uu del\uu
函数之后的所有内容都不有趣)
只要程序中的任何“活动”变量仍然包含对它的引用,GC将永远不会回收您的
记录器
实例。listen(self):…
方法的self
参数就是这样一个变量,它是守护进程线程运行的顶级方法
def _listen(self):
while True:
msg = self.__queue.get()
if msg is None:
break
self.__print_message(msg)
在守护进程线程从\u listen()
返回之前,GC无法回收记录器
实例。只有一种方法可以做到这一点:
def close(self):
self.__queue.put(None)
如果“关闭”记录器,那么守护进程线程最终将从队列中获得None
,它将从\u listen()
调用返回,守护进程线程将结束。但是,你说
我使用守护进程线程的原因是,我不必显式地关闭记录器
如果不关闭记录器,则守护进程线程将永远不会结束,
\u listen(self)
中的self
arg将永远不会超出范围,logger
实例将永远不会被回收。您希望GC在程序终止之前回收logger
实例的原因是什么?守护进程线程应该一直运行到最后,线程的主例程\u listen()
始终通过其self
参数对对象进行实时引用。基本上,我的主张是,即使在程序结束后,垃圾收集器也会删除对象。例如:类X(对象):def uuu init uuuuuuuuuuuuuuuuuuuuuuuuuuuself):打印“创建的…”def uuu del uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuself):打印“已销毁的…”如果uuuuuuuuuuuuuuuuuuu?是否有另一种方法可以实现在不同线程上输出的记录器,而不必担心关闭它?这取决于您所说的“程序结束后”是什么意思。当上面示例中的主线程运行到脚本末尾时,您的class X
实例被删除,我并不感到奇怪。但这与运行而True:…
循环的守护进程线程不同。class X
对象被释放,因为主线程离开了变量X
的作用域。但是原始问题中的守护进程线程何时会离开\u listen(self)
方法中的self
参数的范围?我希望这一过程能在这之前终止。我相信这回答了我的问题。您知道不需要显式关闭记录器(不使用守护进程线程)的任何其他方式吗?最好使用单独的IO线程。您在最初的问题中说,“…当应用程序关闭时…”。我对您的应用程序了解不够,无法了解应用程序“关闭”的所有原因或它是如何“关闭”的。如果其他进程可以显式地终止您的应用程序(例如,在类unix操作系统中使用kill-kill
信号),则任何进程都无法用任何语言“处理”该应用程序。对于任何其他类型的关机,。。。抱歉,但我不是真正的Python大师:我不知道做很多事情的“Python”方法。
def close(self):
self.__queue.put(None)