告诉循环线程停止循环的正确方法是什么?
我有一个相当简单的程序,它在一个单独的类中 ping 指定的主机threading.Thread。在这个类中,它会休眠 60 秒,然后再次运行,直到应用程序退出。
threading.Thread
我想在我的wx.Frame程序中实现一个“停止”按钮,让循环线程停止。它不需要立即结束线程,只要线程被唤醒,它就可以停止循环。
wx.Frame
这是我的threading课程(注意:我还没有实现循环,但它很可能属于 PingAssets 中的运行方法)
threading
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()
在 Python 中,最常见且最合适的停止线程的方法是使用线程安全标志来告诉线程停止其循环。 在您的例子中,PingAssets类可以定期检查此标志(每次睡眠后或在循环中的适当点),如果设置了该标志,它可以退出循环并终止线程。
PingAssets
您可以按照以下方式实现它:
self.stop_event
以下是修改代码以实现这一点的方法:
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()
要从 wxPython 接口停止线程,可以调用stop()以下方法
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()线程的方法,并且线程将在下一次循环迭代时停止(当它唤醒或检查停止标志时)。此方法可确保线程正常停止而不会被强制终止。