簡體   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