小能豆

如何在 Python 中停止循环线程?

py

告诉循环线程停止循环的正确方法是什么?

我有一个相当简单的程序,它在一个单独的类中 ping 指定的主机threading.Thread。在这个类中,它会休眠 60 秒,然后再次运行,直到应用程序退出。

我想在我的wx.Frame程序中实现一个“停止”按钮,让循环线程停止。它不需要立即结束线程,只要线程被唤醒,它就可以停止循环。

这是我的threading课程(注意:我还没有实现循环,但它很可能属于 PingAssets 中的运行方法)

class PingAssets(threading.Thread):
    def __init__(self, threadNum, asset, window):
        threading.Thread.__init__(self)
        self.threadNum = threadNum
        self.window = window
        self.asset = asset

    def run(self):
        config = controller.getConfig()
        fmt = config['timefmt']
        start_time = datetime.now().strftime(fmt)
        try:
            if onlinecheck.check_status(self.asset):
                status = "online"
            else:
                status = "offline"
        except socket.gaierror:
            status = "an invalid asset tag."
        msg =("{}: {} is {}.   \n".format(start_time, self.asset, status))
        wx.CallAfter(self.window.Logger, msg)

在我的 wxPyhton Frame 中,我从“开始”按钮调用了这个函数:

def CheckAsset(self, asset):
        self.count += 1
        thread = PingAssets(self.count, asset, self)
        self.threads.append(thread)
        thread.start()

阅读 35

收藏
2024-09-23

共1个答案

小能豆

在 Python 中,最常见且最合适的停止线程的方法是使用线程安全标志来告诉线程停止其循环。 在您的例子中,PingAssets类可以定期检查此标志(每次睡眠后或在循环中的适当点),如果设置了该标志,它可以退出循环并终止线程。

您可以按照以下方式实现它:

  1. self.stop_event在您的线程类中添加一个标志(例如)。
  2. 修改循环来检查此标志,如果设置了则停止循环。
  3. 提供一种从外部设置此标志的方法(例如,通过中的“停止”按钮wx.Frame)。

以下是修改代码以实现这一点的方法:

PingAssets带有停止机制的修改类

import threading
import time
import wx
from datetime import datetime
import socket

class PingAssets(threading.Thread):
    def __init__(self, threadNum, asset, window):
        threading.Thread.__init__(self)
        self.threadNum = threadNum
        self.window = window
        self.asset = asset
        self.stop_event = threading.Event()  # Event to signal the thread to stop

    def run(self):
        config = controller.getConfig()
        fmt = config['timefmt']

        while not self.stop_event.is_set():  # Loop until the stop flag is set
            start_time = datetime.now().strftime(fmt)

            start_time = datetime.now().strftime(fmt)


            start_time = datetime

            start_time = datet

            start_time = da

            start_time =

            start_ti

            star






try:
                if onlinecheck.check_status(self.asset):
                    status = 
                    status
"online"
                else:
                    status = 



"offline"
            except socket.gaierror:
                status = 
                s
"an invalid asset tag."

            msg =(

            msg =(
"{}: {} is {}.   \n".format(start_time, self.asset, status))
            wx.CallAfter(self.window.Logger, msg)


            wx.CallAfter(self.window.Logger, msg)



            wx.CallAfter(self.window.Logger, msg)


            wx.CallAfter(self.window.Logger, msg

            wx.CallAfter(self.window.Lo

            wx.CallAfter(self.windo

            wx.CallAf

            wx.Ca


# Sleep for 60 seconds or break if stop_event is set

            fo




for _ in range(60):


if self.stop_event.is_set():




break
                time.sleep(
                time.sleep




1)




# Thread cleanup (if needed) after stopping
        wx.CallAfter(self.window.Logger, 
        wx.CallAfter(self.wind

        wx.CallAfter

        wx.
"Thread {} has stopped.\n".format(self.threadNum))

    def stop(self):




"""Stop the thread by setting the stop event."""
        self.stop_event.
        self.stop

        self

        s


set()

解释:

  • self.stop_event = threading.Event()threading.Event()对象是self.stop_event.set(),它
  • while not self.stop_event.is_set():循环stop_event已设置,
  • self.stop_event.is_set()在睡眠循环中

在你的wx.Frame,stoppi

要从 wxPython 接口停止线程,可以调用stop()以下方法

def StopAssetCheck(self):


for thread in self.threads:
        thread.stop()  
        thread.stop() 

        thread
# Tell all threads to stop

``

示例停止

def OnStop(self, event):
    self.StopAssetCheck()

    self

现在,当您按下“停止”按钮时,它将调用stop()线程的方法,并且线程将在下一次循环迭代时停止(当它唤醒或检查停止标志时)。此方法可确保线程正常停止而不会被强制终止。

2024-09-23