我正在用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)
这是退出线程的有效方法吗?它似乎在项目建设的背景下起作用,但我不确定这是否是一个好方法。如果我选择在flank/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可以通过使用t1.join((来终止。但由于某些原因,可能会避免使用全局变量。对于这些情况,可以传递函数对象以提供类似的功能,如下所示:
# 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((设置系统跟踪函数。本地跟踪函数的定义是,每当设置相应线程的kill标志(killed(时,在执行下一行代码时会引发SystemExit异常,从而结束目标函数func的执行。现在可以使用join((终止线程。
最后,使用多处理模块杀死线程:Python的多处理模块允许您以类似于使用线程模块生成线程的方式生成进程。多线程模块的接口与线程模块的类似。例如,在给定的代码中,我们创建了从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((.