我wrote a class继承自 object 并且具有使用某些线程执行任务的子对象实例。有两个socket 侦听器为每个 accept ed连接创建其他线程。他们做他们必须做的事。要完成它们,他们正在查看 Threading.Event 对象以了解它们必须完成。
我注意到,当退出python控制台时,他们没有得到通知(或者没有捕获通知),并且退出不会将控制权返回给bash控制台,除非 Close()之前被调用。
修复它的第一个想法是实现'__ del __'方法,以便在退出时使用垃圾收集器清除它。
class ServiceProvider(object):
def __init__(self):
super(ServiceProvider,self).__init__()
#...
self.Open()
def Open(self):
#... Some threads are created.
def Close(self):
#.... Threading.Event to report the threads to finish
def __del__(self):
self.Close()
但行为是一样的。如果我在这些方法中放置一个打印件,不在'__ del __'中,在'Close'中都不会写入。除非之前关闭,否则会写入 del 中的打印。
然后我实现了'__ enter __'和'__ exit __'方法来管理 with 语句。并且 exit 按预期运行,当 with 结束时,事情就会释放。但我真正想要的是像文件描述符这样的事件,如果没有调用 file.close(),它会在退出程序时执行。
class ServiceProvider(object):
#...
def __enter__(self):
return self
def __exit__(self):
self.Close()
正在搜索我尝试使用atexit的更多解决方案,但不是。我有类似的结果,不能解决问题。即使我收集了此类创建的所有对象,如果列表中的对象已经关闭, doOnExit 也只会写入其打印。
import atexit
global objects2Close
objects2Close = []
@atexit.register
def doOnExit():
for obj in objects2Close:
obj.Close()
class ServiceProvider(object):
def __init__(self):
super(ServiceProvider,self).__init__()
objects2Close.append(self)
答案 0 :(得分:0)
当您拥有不想泄露的资源(文件,连接以及您关心的任何其他内容)时,使用with
通常是个好主意。
在某个地方,就在你的主循环之外你应该有:
with ServiceProvider(some_params) as service_provider:
rest_of_the_code()
这样做无论你如何退出rest_of_the_code()(kill -9除外),它都会在最后调用service_provider.Close()。这也适用于异常和中断。杀死-9不起作用,因为该进程在操作系统级别被杀死,并且没有机会尝试恢复。
答案 1 :(得分:0)
我已经找到了解决这个问题的方法。此问题中发布的信息与实际问题无关。
这就像守护程序线程一样简单。
该实现使用一些线程来监听远程连接,他们必须在程序退出时完成执行。但是当所有 no daemon 线程完成时,程序结束。
错误地将那些未设置为守护进程的听众和谈话者,这就是执行等待他们的原因。