Skip to main content
 首页 » 编程设计

Python,停止一个线程

2025年05月04日20TianFang

我正在尝试创建一个类来 ping 一个 IP 地址并记录连接/未连接的时间。

因为这个类是 GUI 的一部分,我希望在用户询问时停止这个线程。

发现了一些对这个问题进行重新分级的问答,但没有一个真正导致线程停止。

我正在尝试创建一个方法,该类的一部分将停止 self.run()

这是我的 Pinger 类:

class Pinger(threading.Thread): 
    def __init__(self, address='', rate=1): 
        threading.Thread.__init__(self) 
 
        self.address = address 
        self.ping_rate = rate 
        self.ping_vector, self.last_ping = [], -1 
        self.start_time, self.last_status = datetime.datetime.now(), [] 
        self.timestamp, self.time_vector = 0, [datetime.timedelta(0)] * 4 
 
    def run(self): 
            self.start_ping() 
 
    def start_ping(self): 
        self.timestamp = datetime.datetime.now() 
        while True: 
            ping_result = os.system('ping %s -n 1 >Null' % self.address) 
            self.ping_vector.append(ping_result) 
 
            if self.last_ping != ping_result: 
                text = ['Reachable', 'Lost'] 
                print(str(self.timestamp)[:-4], self.address, text[ping_result]) 
 
            round_time_qouta = datetime.datetime.now() - self.timestamp 
            self.timestamp = datetime.datetime.now() 
            self.update_time_counter(ping_result, round_time_qouta) 
 
            self.last_ping = ping_result 
            time.sleep(self.ping_rate) 
 
    def update_time_counter(self, ping_result=0, time_quota=datetime.timedelta(0)): 
        """self.time_vector = [[cons.succ ping time],[cons.not_succ ping time], 
        [max accum succ ping time],[max accum not_succ ping time] """ 
 
        p_vec = [0, 1] 
 
        self.time_vector[p_vec[ping_result]] += time_quota 
        if self.time_vector[p_vec[ping_result]].total_seconds() > self.time_vector[ 
            p_vec[ping_result] + 2].total_seconds(): 
            self.time_vector[p_vec[ping_result] + 2] = self.time_vector[p_vec[ping_result]] 
 
        self.time_vector[p_vec[ping_result - 1]] = datetime.timedelta(0) 
 
        self.last_status = [ping_result, self.chop_milisecond(self.time_vector[ping_result]), 
                            self.chop_milisecond(self.time_vector[ping_result + 2]), 
                            self.chop_milisecond(datetime.datetime.now() - self.start_time)] 
 
        print(str(self.timestamp)[:-4], "State: " + ['Received', 'Lost'][ping_result], 
              " Duration: " + self.last_status[1], " Max Duration: " + self.last_status[2], 
              "Total time: " + self.last_status[3]) 
 
    def chop_milisecond(self, time): 
        return str(time).split('.')[0] 

请您参考如下方法:

正如我在评论中所说,最简单的方法是使用 threading.Event在线程应该退出时发出信号。这样您就可以公开该事件并让其他线程设置它,同时您可以从您的线程中检查它的状态并根据请求退出。

在您的情况下,它可能很简单:

class Pinger(threading.Thread): 
 
    def __init__(self, address='', rate=1): 
        threading.Thread.__init__(self) 
        self.kill = threading.Event() 
        # the rest of your setup... 
 
    # etc. 
 
    def start_ping(self): 
        self.timestamp = datetime.datetime.now() 
        while not self.kill.is_set(): 
            # do your pinging stuff 
 
    # etc. 

然后,无论何时您希望线程停止(例如从您的 UI),只需调用它:pinger_instance.kill.set() 即可。不过请记住,由于阻塞 os.system() 调用和 time.sleep(),它需要一些时间才能被杀死您在 Pinger.start_ping() 方法的末尾。