Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python/wxPython中不停止/杀死所有生成的线程有什么不良影响_Python_Multithreading_Python 2.7_Wxpython - Fatal编程技术网

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

在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

我正在使用Windows7操作系统上的PythonV2.7和Wxpython3.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()

感谢您的时间,我们将非常感谢您的帮助。

嗨,mate,看看这篇文章中给出的终止线程的解决方案


我希望它能帮助你解决你的问题:)

好吧,原来的方式不好,线程一直保持活动状态,不断向一个不存在的GUI发送更新。这导致它对C++位不真实或一些无稽之谈产生了严重错误。但通过进行以下更改,您可以很容易地避免这种情况:

  • 在GUI的
    \uuuu init\uuuu()方法中创建线程,并将其创建为类属性
  • 让GUI的
    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
    窗口