繁体   English   中英

不停止/杀死python / wxPython中所有生成的线程有什么不好的影响

[英]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 ++位不是真实的或一些这样的废话。 但是,您可以通过进行以下更改来轻松避免这种情况:

  1. 在GUI的__init__()方法中创建线程并将其创建为类属性
  2. 让GUI的closeWindow()方法从线程中取消订阅(以防止在关闭后传输)
  3. 通过更改我添加的参数( running )来通知线程停止传输
  4. 将线程创建为守护程序
  5. 修改线程中的while循环以基于新的running参数,以便可以告知何时停止
  6. 告诉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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM