Python线程。如果类拥有正在运行的线程,则不会被删除

2024-10-06 11:28:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图创建一个python包来调用非阻塞命令。我想到的是一个简单的“Executer”类,它将有一个线程和一个队列,其中包含一个接一个执行的命令。虽然命令的执行似乎有效,但程序永远不会退出,因为在对象超出作用域后,executer类永远不会被垃圾收集器删除。你知道吗

import threading
import queue
import time
import weakref

class Commands:
    """Class for all Commands"""
    Command: str = ""
    IsDone: bool = False
    WasSuccessfull: bool = False
    Value: object = None

    def __init__(self, InputCommand):
        self.Command = InputCommand

    def GetValue(self) -> object:
        while not self.IsDone:
            time.sleep(0.01)

        return self.Value

    def WaitForFinished(self):
        while not self.IsDone:
            time.sleep(0.01)



class Executer:       
    CommandQueue: queue.Queue = queue.Queue()
    Worker: threading.Thread = None

    def __init__(self):
        self.Worker = threading.Thread(target=weakref.proxy(Executer.__WorkerThread__), args=(weakref.proxy(self) ,))
        self.Worker.start()


    def __del__(self):
        print("Exiting")
        self.AddCommand("__STOP__")
        self.Worker.join()


    def AddCommand(self, CommandText) -> Commands:
        Command = Commands(CommandText)
        self.CommandQueue.put(Command)
        return Command

    def __WorkerThread__ (self):
        while True:
            if self.CommandQueue.empty():
                time.sleep(0.01)
            else:
                Command = self.CommandQueue.get()
                print(Command.Command)
                # Emulate some work
                time.sleep(0.5)
                Command.IsDone = True
                Command.WasSuccessfull = True
                if(Command.Command == "__STOP__"):
                    break


if __name__ == "__main__":
    exe = Executer()
    Command = exe.AddCommand("Yeah 0")
    exe.AddCommand("Yeah 1")
    exe.AddCommand("Yeah 2")
    exe.AddCommand("Yeah 3")
    exe.AddCommand("Yeah 4")
    x = Command.GetValue()
    print(x)
    print("Done")

似乎和这里提到的问题是一样的: Python threading.Thread, scopes and garbage collection

虽然这个解决方案(在他的评论中)似乎对作者有效,但在整合它之后,它对我不起作用。主线程将运行槽,我的所有命令将得到执行,但子线程不会死,因为“executer”类不会被删除。你知道吗

如果用户专门调用了del exe,那么类就会被删除,但是这不是一个好的python方法,因为我的包的用户总是需要自己清理类。你知道吗


Tags: import命令selftimedefsleepexecommand