Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 带有守护进程线程的单例垃圾收集器_Python_Multithreading_Garbage Collection_Singleton_Daemon - Fatal编程技术网

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)