本文介绍了在关闭交互式Python会话时结束非守护程序线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
请考虑以下代码:
#! /usr/bin/env python3
import threading
import time
class MyThread(threading.Thread):
def __init__(self):
super().__init__()
self._quit_flag = False
def run(self):
while not self._quit_flag:
print("Thread is alive!")
time.sleep(0.500)
def request_quit(self):
self._quit_flag = True
mt = MyThread()
mt.start()
在将其另存为‘test.py’并运行‘python3-i test.py’之后,我得到了一个交互会话,在该会话中,线程定期打印"Thread is live!"消息。
当我按Ctrl-D或Run Exit()时,python3进程不会终止,因为线程仍在运行。我想解决这个问题。
但是,我不想使该线程成为守护进程线程--我希望能够正确地结束/加入该线程,因为在我要解决的实际情况中,我希望很好地终止网络连接。
有没有办法做到这一点?例如,在REPL循环终止之后、就在主线程退出之前执行的某个挂钩是否可用?
推荐答案
好的,我自己找到了一种方法。
查看Python源代码,发现在关闭时,在完成进程关闭之前,Python会尝试加入()所有非守护进程线程。这是有意义的,除了如果有一种有文档记录的方式来通知这些线程,这会更有用。但事实并非如此。但是,可以重新实现从Thread派生的自己的类的Join()方法,这可以作为通知子线程应该关闭自身的一种方式:
class MyThread(threading.Thread):
def __init__(self):
super().__init__()
self._quit_flag = False
def __del__(self):
print("Bye bye!")
def run(self):
while not self._quit_flag:
print("Thread is alive!", threading.active_count(), threading.main_thread().is_alive())
for t in threading.enumerate():
print(t.is_alive())
time.sleep(0.500)
def request_quit(self):
self._quit_flag = True
def join(self):
self.request_quit()
super().join()
然而,这种解决问题的方法几乎是一种黑客行为,它忽略了‘线程’模块文档(https://docs.python.org/3/library/threading.html)中的以下段落:
Thread类表示在单独的 控制的线索。有两种方式可以指定活动:按 将可调用对象传递给构造函数,或通过重写 子类中的run()方法。没有其他方法(除了 构造函数)应在子类中重写。换句话说,只有 重写此类的__init__()和run()方法。
然而,它确实工作得很好。
这篇关于在关闭交互式Python会话时结束非守护程序线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!