[英]What are the bad effects of not stopping/killing all the spawned threads in python/wxPython
我正在使用Windows 7操作系统上的python v2.7和wxPython 3.0的GUI应用程序。 我有一个关于线程的一般问题。 在我的程序中,我正在创建一个将不断更新我的GUI的线程。 如果我关闭GUI窗口,似乎一切都已关闭并且很好。 从命令提示符执行我的代码时,我发现线程不断向GUI发送更新。
问题 :由于我的GUI正确更新,甚至在没有任何崩溃的情况下关闭,我是否应该在关闭GUI窗口后烦恼仍在努力更新GUI的线程? 如果这是一个非常严重的问题?
如果有人可以建议我如何修改我的closeWindow()
以便在GUI关闭时它首先杀死线程,那就太好了。
代码 :这是一个示例代码。 请从console / cmd执行代码然后你会发现我的问题。
import wx
from wx.lib.pubsub import setupkwargs
from wx.lib.pubsub import pub
import time
from threading import Thread
class GUI(wx.Frame):
def __init__(self, parent, id, title):
screenWidth = 500
screenHeight = 400
screenSize = (screenWidth,screenHeight)
wx.Frame.__init__(self, None, id, title, size=screenSize)
self.locationFont = locationFont = wx.Font(12, wx.MODERN, wx.NORMAL, wx.BOLD)
mainSizer = wx.BoxSizer(wx.VERTICAL)
myPanelA = wx.Panel(self, style=wx.SIMPLE_BORDER)
myPanelA.SetBackgroundColour('#C0FAE0')
self.myTextA = wx.StaticText(myPanelA, -1, "Testing")
mainSizer.Add(myPanelA, 1, wx.EXPAND, 5)
self.SetSizer(mainSizer)
self.Bind(wx.EVT_CLOSE, self.closeWindow)
pub.subscribe(self.updatePanelA, 'Update-panelA')
def updatePanelA(self, message):
self.myTextA.SetLabel(message)
def closeWindow(self, event):
# --> Code for killing the thread :)
self.Destroy()
class threadA(Thread):
def __init__(self):
Thread.__init__(self)
self.start()
def run(self):
ObjA = updateGUI()
ObjA.methodA()
class updateGUI():
def methodA(self):
while True:
time.sleep(2)
print 'Sending update'
wx.CallAfter(pub.sendMessage, 'Update-panelA', message='Yes, It works')
if __name__=='__main__':
app = wx.App()
frame = GUI(parent=None, id=-1, title="Problem Demo-PSS")
frame.Show()
threadA()
app.MainLoop()
感谢您的时间和任何帮助将不胜感激。
好吧,它的方式不好,线程被活着,不断向不存在的GUI发送更新。 这导致它抛出一个令人讨厌的错误,关于C ++位不是真实的或一些这样的废话。 但是,您可以通过进行以下更改来轻松避免这种情况:
__init__()
方法中创建线程并将其创建为类属性 closeWindow()
方法从线程中取消订阅(以防止在关闭后传输) running
)来通知线程停止传输 while
循环以基于新的running
参数,以便可以告知何时停止 app
没有重定向( app = wx.App(False)
) 考虑到所有这些因素,您将获得以下代码:
import wx
from wx.lib.pubsub import setupkwargs
from wx.lib.pubsub import pub
import time
import threading
class GUI(wx.Frame):
def __init__(self, parent, id, title):
screenWidth = 500
screenHeight = 400
screenSize = (screenWidth,screenHeight)
wx.Frame.__init__(self, None, id, title, size=screenSize)
self.locationFont = locationFont = wx.Font(12, wx.MODERN, wx.NORMAL, wx.BOLD)
mainSizer = wx.BoxSizer(wx.VERTICAL)
myPanelA = wx.Panel(self, style=wx.SIMPLE_BORDER)
myPanelA.SetBackgroundColour('#C0FAE0')
self.myTextA = wx.StaticText(myPanelA, -1, "Testing")
mainSizer.Add(myPanelA, 1, wx.EXPAND, 5)
self.SetSizer(mainSizer)
self.Bind(wx.EVT_CLOSE, self.closeWindow)
pub.subscribe(self.updatePanelA, 'Update-panelA')
self.thd = threadA()
def updatePanelA(self, message):
self.myTextA.SetLabel(message)
def closeWindow(self, event):
# --> Code for killing the thread :)
pub.unsubscribe(self.updatePanelA, 'Update-panelA')
self.thd.running = False
self.Destroy()
class threadA(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.daemon = True
self.running = True
self.start()
def run(self):
while self.running:
time.sleep(2)
print 'Sending update'
wx.CallAfter(pub.sendMessage, 'Update-panelA', message='Yes, It works')
if __name__=='__main__':
app = wx.App(False)
frame = GUI(parent=None, id=-1, title="Problem Demo-PSS")
frame.Show()
app.MainLoop()
希望这可以帮助
您的问题: 由于我的GUI正确更新,甚至关闭而没有任何崩溃,我是否应该在关闭GUI窗口后烦恼仍在努力更新GUI的线程? 如果这是一个非常严重的问题?
这是非常严重的关注。
一些线程可以只是为了提供“主线程之外的计算资源”,但是许多(如果不是大多数)线程用于访问系统资源,例如套接字,串行端口等。
在这些情况下,资源已由线程打开并且由线程独占,因此任何其他需要该资源的进程都无法获取它,并且可能更重要的是,如果再次重新运行程序,它将无法工作,因为先前的线程拥有您需要的资源。
学习使用操作系统的线程查看器(和线程查杀程序)。 你需要它们。 然后编写自己的程序,以便不需要它们(通过适当的线程控制)。
嗨伙伴检查解决方案给这个帖子杀死线程使用sys.exit()终止python线程
我希望它能帮助你解决问题:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.