我正在用 python 编写一个计时器。当计时器达到 0 时,我希望我创建的线程自动退出。
class Rollgame:
timer = 0
def timerf(self, timer):
self.timer = timer
while self.timer > 0:
time.sleep(0.1)
self.timer -= 0.1
sys.exit(0)
这是退出线程的有效方法吗?它似乎在我正在构建的程序的上下文中工作,但是我不确定这是否是一个好方法。 如果我选择在 Flask/django 应用程序中实现这一点,这仍然有效吗? 抱歉,如果这个问题看起来很愚蠢或太简单,我以前从未在 python 中使用过线程。
最佳答案
一般来说,突然终止线程被认为是一种不好的编程习惯。突然终止线程可能会使必须正确关闭的关键资源保持打开状态。但是,一旦经过某个特定时间段或生成某个中断,您可能希望终止线程。您可以通过多种方法来终止 python 中的线程。
设置/重置停止标志: 为了杀死一个线程,我们可以声明一个停止标志,并且线程偶尔会检查该标志。例如:
# Python program showing
# how to kill threads
# using set/reset stop
# flag
import threading
import time
def run():
while True:
print('thread running')
global stop_threads
if stop_threads:
break
stop_threads = False
t1 = threading.Thread(target = run)
t1.start()
time.sleep(1)
stop_threads = True
t1.join()
print('thread killed')
在上面的代码中,一旦设置了全局变量stop_threads,目标函数run()就会结束,并且可以使用t1.join()杀死线程t1。但由于某些原因,人们可能会避免使用全局变量。对于这些情况,可以传递函数对象来提供类似的功能,如下所示:
# Python program killing
# threads using stop
# flag
import threading
import time
def run(stop):
while True:
print('thread running')
if stop():
break
def main():
stop_threads = False
t1 = threading.Thread(target = run, args =(lambda : stop_threads, ))
t1.start()
time.sleep(1)
stop_threads = True
t1.join()
print('thread killed')
main()
使用跟踪来终止线程: 此方法的工作原理是在每个线程中安装跟踪。每个跟踪都会在检测到某些刺激或标志时自行终止,从而立即终止关联的线程。例如:
# Python program using
# traces to kill threads
import sys
import trace
import threading
import time
class thread_with_trace(threading.Thread):
def __init__(self, *args, **keywords):
threading.Thread.__init__(self, *args, **keywords)
self.killed = False
def start(self):
self.__run_backup = self.run
self.run = self.__run
threading.Thread.start(self)
def __run(self):
sys.settrace(self.globaltrace)
self.__run_backup()
self.run = self.__run_backup
def globaltrace(self, frame, event, arg):
if event == 'call':
return self.localtrace
else:
return None
def localtrace(self, frame, event, arg):
if self.killed:
if event == 'line':
raise SystemExit()
return self.localtrace
def kill(self):
self.killed = True
def func():
while True:
print('thread running')
t1 = thread_with_trace(target = func)
t1.start()
time.sleep(2)
t1.kill()
t1.join()
if not t1.isAlive():
print('thread killed')
在此代码中,start() 稍作修改,以使用 settrace() 设置系统跟踪函数。本地跟踪函数的定义是,每当设置相应线程的终止标志(killed)时,在执行下一行代码时会引发 SystemExit 异常,从而结束目标函数 func 的执行。现在可以使用 join() 终止线程。
最后,使用多处理模块杀死线程: Python 的多处理模块允许您以与使用 threading 模块生成线程类似的方式生成进程。多线程模块的接口(interface)与线程模块的接口(interface)类似。例如,在给定的代码中,我们创建了三个线程(进程),从 1 计数到 9。现在,假设我们想要终止所有线程。您可以使用多处理来做到这一点。
# Python program killing
# a thread using multiprocessing
# module
import multiprocessing
import time
def func(number):
for i in range(1, 10):
time.sleep(0.01)
print('Processing ' + str(number) + ': prints ' + str(number*i))
# list of all processes, so that they can be killed afterwards
all_processes = []
for i in range(0, 3):
process = multiprocessing.Process(target=func, args=(i,))
process.start()
all_processes.append(process)
# kill all processes after 0.03s
time.sleep(0.03)
for process in all_processes:
process.terminate()
综上所述,终止线程的方法有很多,但我个人不会使用sys.exit()。
关于python - sys.exit(0) 是退出/终止 python 线程的有效方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65630708/