Python 杀死线程

Vaibhhav Khetarpal 2023年1月30日
  1. 在 Python 中在线程中引发异常以终止线程
  2. 在 Python 中使用 trace 杀死一个线程
  3. 在 Python 中创建/重置停止标志以终止线程
  4. 在 Python 中使用 multiprocessing 模块杀死一个线程
  5. 在 Python 中将给定线程设置为守护线程以终止线程
  6. 使用隐藏的 _stop() 函数杀死 Python 中的线程
Python 杀死线程

尽管它在程序员中被标记为一种不好的编程习惯,但有时在 Python 中可能仍然需要杀死一个线程。本教程演示了我们可以在 Python 中终止线程的不同方法。

突然结束威胁的缺点可能会使任务在后台打开,从而导致问题。

而且,Python 没有提供任何直接杀死 Python 中的线程的方法,这意味着要找到漏洞和间接方法来实现这一基本任务。

现在,我们将重点介绍并解释在 Python 中杀死线程的几种方法。

在 Python 中在线程中引发异常以终止线程

此方法利用 PyThreadState_SetAsyncExc() 函数,该函数在给定线程中异步引发异常。

以下代码在线程中引发异常以终止 Python 中的线程。

import threading
import ctypes
import time


class twe(threading.Thread):
    def __init__(self, name):
        threading.Thread.__init__(self)
        self.name = name

    def run(self):
        try:
            while True:
                print("running " + self.name)
        finally:
            print("ended")

    def get_id(self):
        if hasattr(self, "_thread_id"):
            return self._thread_id
        for id, thread in threading._active.items():
            if thread is self:
                return id

    def raise_exception(self):
        thread_id = self.get_id()
        resu = ctypes.pythonapi.PyThreadState_SetAsyncExc(
            thread_id, ctypes.py_object(SystemExit)
        )
        if resu > 1:
            ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, 0)
            print("Failure in raising exception")


x = twe("Thread A")
x.start()
time.sleep(2)
x.raise_exception()
x.join()

当代码运行时,一旦引发异常,run() 函数将被终止,因为程序控制可以绕过异常处理程序的 try 块。

然后调用 join() 函数以给予最后一击并杀死 run() 函数。

在 Python 中使用 trace 杀死一个线程

在 Python 中实现杀死线程的相同任务的另一种方法是在给定线程中安装 trace,改变线程的执行。

以下代码使用跟踪来终止 Python 中的线程。

import sys
import time
import threading
import trace


class KThread(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, why, arg):
        if why == "call":
            return self.localtrace
        else:
            return None

    def localtrace(self, frame, why, arg):
        if self.killed:
            if why == "line":
                raise SystemExit()
        return self.localtrace

    def kill(self):
        self.killed = True


def exfu():
    print("The function begins")
    for i in range(1, 100):
        print(i)
        time.sleep(0.2)
    print("The function ends")


x = KThread(target=exfu)
x.start()
time.sleep(1)
x.kill()

上面的代码提供了以下输出。

The function begins
1
2
3
4
5

在这里,我们使用了 KThread 类,它是原始 threading.Thread 类的一个子集。KThread 类使 kill() 函数在代码中实现。

在 Python 中创建/重置停止标志以终止线程

可以在代码中声明一个停止标志,这将使它在遇到线程时停止线程的执行。

以下代码创建一个停止标志来终止 Python 中的线程。

import threading
import time


def frun():
    while True:
        print("thread running")
        global stop_threads
        if stop_threads:
            break


stop_threads = False
x = threading.Thread(target=frun)
x.start()
time.sleep(1)
stop_threads = True
x.join()
print("killed the thread.")

在 Python 中使用 multiprocessing 模块杀死一个线程

multiprocessing 模块使得产生进程成为可能,其方法和工作类似于 threading 模块,因为它们都使用 API。

terminate() 可以杀死一个给定的进程,这比杀死一个线程本身更安全,也更简单。

以下代码使用 multiprocessing 模块杀死 Python 中的线程。

import multiprocessing
import time


def cp():
    while True:
        for i in range(20):
            print("Process: ", i)
            time.sleep(0.05)


x = multiprocessing.Process(target=cp)
x.start()
time.sleep(0.5)
x.terminate()
print("Terminated the child process")

在 Python 中将给定线程设置为守护线程以终止线程

守护线程是在主程序终止时自动终止的线程。我们可以将给定的线程设置为守护线程来杀死 Python 中的特定线程。

以下代码将给定线程设置为守护线程以终止 Python 中的线程。

import threading
import time
import sys


def exfu():
    while True:
        time.sleep(0.5)
        print("Thread alive, but it will die on program termination")


x = threading.Thread(target=exfu)
x.daemon = True
x.start()
time.sleep(2)
sys.exit()

使用隐藏的 _stop() 函数杀死 Python 中的线程

尽管没有记录,隐藏的 _stop() 函数可以实现在 Python 中杀死线程的任务。

以下代码使用隐藏的 _stop() 函数来终止 Python 中的线程。

import time
import threading


class th1(threading.Thread):
    def __init__(self, *args, **kwargs):
        super(th1, self).__init__(*args, **kwargs)
        self._stop = threading.Event()

    def stop(self):
        self._stop.set()

    def stopped(self):
        return self._stop.isSet()

    def run(self):
        while True:
            if self.stopped():
                return
            print("Hello, world!")
            time.sleep(1)


x = th1()
x.start()
time.sleep(5)
x.stop()
x.join()
Vaibhhav Khetarpal avatar Vaibhhav Khetarpal avatar

Vaibhhav is an IT professional who has a strong-hold in Python programming and various projects under his belt. He has an eagerness to discover new things and is a quick learner.

LinkedIn

相关文章 - Python Thread