在python/wxPython中不停止/杀死所有生成的线程有什么不良影响
我正在使用Windows7操作系统上的PythonV2.7和Wxpython3.0开发GUI应用程序。 我有一个关于线程的一般性问题。在我的程序中,我正在创建一个线程,该线程将不断更新我的GUI。如果我关闭GUI窗口,似乎一切都已关闭,一切正常。然而,在从命令提示符执行代码时,我发现线程一直在向GUI发送更新 问题:由于我的GUI正在正确更新,甚至关闭时没有任何崩溃,我是否应该担心在关闭GUI窗口后仍在努力更新GUI的线程?如果这是一个非常严重的问题 如果有人能建议我如何修改我的在python/wxPython中不停止/杀死所有生成的线程有什么不良影响,python,multithreading,python-2.7,wxpython,Python,Multithreading,Python 2.7,Wxpython,我正在使用Windows7操作系统上的PythonV2.7和Wxpython3.0开发GUI应用程序。 我有一个关于线程的一般性问题。在我的程序中,我正在创建一个线程,该线程将不断更新我的GUI。如果我关闭GUI窗口,似乎一切都已关闭,一切正常。然而,在从命令提示符执行代码时,我发现线程一直在向GUI发送更新 问题:由于我的GUI正在正确更新,甚至关闭时没有任何崩溃,我是否应该担心在关闭GUI窗口后仍在努力更新GUI的线程?如果这是一个非常严重的问题 如果有人能建议我如何修改我的closeWin
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()
感谢您的时间,我们将非常感谢您的帮助。嗨,mate,看看这篇文章中给出的终止线程的解决方案
我希望它能帮助你解决你的问题:)好吧,原来的方式不好,线程一直保持活动状态,不断向一个不存在的GUI发送更新。这导致它对C++位不真实或一些无稽之谈产生了严重错误。但通过进行以下更改,您可以很容易地避免这种情况:
\uuuu init\uuuu()方法中创建线程,并将其创建为类属性
closeWindow()
方法从线程中取消订阅(以防止关闭后的传输)正在运行
),向线程发出停止传输的信号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的线程?如果这是一个非常严重的问题
这是一个非常严重的问题
有些线程可能只是为了提供“主线程之外的计算资源”,但是很多次(如果不是大多数的话)线程被用来访问系统资源,如套接字、串行端口等
在这些情况下,资源已经被线程打开并且完全由线程所有,因此任何其他需要该资源的进程都无法获取资源,而且可能更重要的是,如果您再次重新运行程序,它将无法工作,因为先前的线程拥有您需要的资源
学习使用操作系统的线程查看器(和线程终止例程)。
你需要它们。
然后编写自己的程序,这样就不需要它们(通过适当的线程控制).有什么原因使
methodA
不是线程的一部分吗?这会有什么不同吗?当GUI窗口关闭时,线程仍然处于无限循环中,不会死亡,我测试了它。它不会立即产生任何不同,它只会清理代码,从而使调试更容易。谢谢。你能给我解释一下是什么吗“app=wx.app(False)”与“app=wx.app()”相比是否有效?我不理解这些文档。因此,False
是重定向的值。如果cmd
用完,使用此值将发送任何输出,而True
(或无值)将在创建输出时打开一个新的stdout
窗口