繁体   English   中英

sys.exit(0) 是退出/杀死 python 中的线程的有效方法吗?

[英]Is sys.exit(0) a valid way to exit/kill a thread in python?

我正在 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)

这是退出线程的有效方法吗? 它似乎在我正在构建的程序的上下文中工作,但是我不确定这是否是一个好方法。 如果我选择在诸如烧瓶/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,目标 function run() 就结束了,线程 t1 可以通过使用 t1.join() 来杀死。 但是由于某些原因,人们可能会避免使用全局变量。 对于这些情况,可以传递 function 对象以提供类似的功能,如下所示:

# 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() 设置系统跟踪 function。 本地跟踪 function 被定义为,只要设置了相应线程的终止标志(已终止),就会在执行下一行代码时引发 SystemExit 异常,从而结束目标 function 函数的执行。 现在可以使用 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()。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM