【问题标题】:Python - Cannot join thread - No multiprocessingPython - 无法加入线程 - 没有多处理
【发布时间】:2016-10-06 18:16:32
【问题描述】:

我的程序中有这段代码。其中 OnDone 函数是 wxPython GUI 中的一个事件。当我单击 DONE 按钮时,会触发 OnDone 事件,然后执行一些功能并启动线程 self.tstart - 使用目标函数 StartEnable。我想使用 self.tStart.join() 重新加入这个线程。但是我收到如下错误:

Exception in thread StartEnablingThread:
Traceback (most recent call last):
  File "C:\Python27\lib\threading.py", line 801, in __bootstrap_inner
    self.run()
  File "C:\Python27\lib\threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "//wagnernt.wagnerspraytech.com/users$/kundemj/windows/my documents/Production GUI/Trial python Codes/GUI_withClass.py", line 638, in StartEnable
    self.tStart.join()
  File "C:\Python27\lib\threading.py", line 931, in join
    raise RuntimeError("cannot join current thread")
RuntimeError: cannot join current thread

我以前没有遇到过这种类型的错误。你们中的任何人都可以告诉我我在这里缺少什么。

    def OnDone(self, event):
        self.WriteToController([0x04],'GuiMsgIn')
        self.status_text.SetLabel('PRESSURE CALIBRATION DONE \n DUMP PRESSURE')
        self.led1.SetBackgroundColour('GREY')
        self.add_pressure.Disable()
        self.tStart = threading.Thread(target=self.StartEnable, name = "StartEnablingThread", args=())
        self.tStart.start()

    def StartEnable(self):
        while True:
            time.sleep(0.5)
            if int(self.pressure_text_control.GetValue()) < 50:
                print "HELLO"
                self.start.Enable()
                self.tStart.join()
                print "hello2"
                break

我想在“if”条件执行后加入线程。直到他们我希望线程运行。

【问题讨论】:

    标签: python multithreading wxpython


    【解决方案1】:

    正在等待加入

    加入一个线程实际上意味着等待另一个线程完成。

    所以,在thread1 中,可以有这样的代码:

    thread2.join()
    

    这意味着“在thread2完成之前不要执行下一行代码”。

    如果您(在 thread1 中)执行以下操作,则会因问题中的错误而失败:

    thread1.join()    # RuntimeError: cannot join current thread
    

    加入不会停止

    调用thread2.join() 不会导致thread2 停止,甚至也不会以任何方式向它发出应该停止的信号。

    线程在其目标函数退出时停止。通常,一个线程被实现为一个循环,它检查一个告诉它停止的信号(一个变量),例如

    def run():
        while whatever:
            # ...
            if self.should_abort_immediately:
                print 'aborting'
                return
    

    那么,停止线程的方法是:

    thread2.should_abort_immediately = True  # tell the thread to stop
    thread2.join()  # entirely optional: wait until it stops
    

    问题中的代码

    该代码已经使用break 正确实现了停止。 join 应该被删除。

            if int(self.pressure_text_control.GetValue()) < 50:
                print "HELLO"
                self.start.Enable()
                print "hello2"
                break
    

    【讨论】:

    • 谢谢 Zvone,很好的回答。我只有一个后续问题:
    • 谢谢 Zvone,很好的回答。我只有一个后续问题:我在一个 Python 文件中启动一个线程,其目标函数在另一个 Python 文件中。我应该在哪里声明 should_abort_immediately?我应该这样做是我的第一个文件还是第二个文件中的全局变量?最后,我想从第一个 python 文件中停止线程。
    • @JeshKundem 我通常为每个线程创建一个类(继承自Thread)。这样就更容易跟踪在哪个线程中执行了哪些代码。将线程放在单独的文件中是完美的。该变量绝对应该在线程的代码中。我喜欢在设置变量的线程中还有一个stop(self) 方法,然后是joins。然后你就从外部调用它。
    • 您肯定回答了这个问题,但我无法弄清楚您如何通过从外部设置变量来返回线程目标函数。我仍然在敲我的头。您可以在此处找到示例代码:stackoverflow.com/questions/39921570/…
    • @JeshKundem 我在那里给了你答案:stackoverflow.com/a/39926065/389289
    【解决方案2】:

    当StartEnable 方法正在执行时,它在您在__init__ 方法中创建的StartEnablingThread 上运行。您无法加入当前线程。这在join 调用的文档中有明确说明。

    如果尝试加入当前线程,

    join() 会引发 RuntimeError,因为这会导致死锁。在线程启动之前加入()线程也是一个错误,并且尝试这样做会引发相同的异常。

    【讨论】:

      【解决方案3】:

      我有一些坏消息。 Python 中的线程是毫无意义的,您最好只考虑使用 1 个线程或使用多进程。如果您需要查看线程,那么您将需要查看其他语言,例如 C# 或 C。请查看 https://docs.python.org/2/library/multiprocessing.html

      线程在 python 中毫无意义的原因是全局解释器锁 (GIL)。这使您一次只能使用一个线程,因此 python 中没有多线程,但有人在研究它。 http://pypy.org/

      【讨论】:

      • Python 中的线程并非毫无意义。它有其局限性,但在许多情况下它仍然比多处理更好。
      • 嗯...你是不是也说不能在只有一个核心的 CPU 上使用线程?或者进程,就此而言,因为一个 CPU 内核一次只能运行一件事......
      • 不要将线程与并行处理混淆。线程允许一段正在等待某事的代码将处理器时间让给另一段代码。它不能保证这两个线程能够同时运行,只有在线程切换足够快的情况下才会出现这种情况。
      • 我确实阅读了整篇文章,但我仍然坚持我原来的观点。线程早在多核处理器之前就已经存在,并且首先被用作分时 CPU 的一种方式,并允许它通过不断地在运行的线程之间切换来给人一种能够同时执行多个任务的印象。并行处理利用在多个内核上同时运行多个线程。许多 CPU 仍将在同一个内核上从单个进程运行线程,除非明确指示在另一个内核上运行它。
      • 底线是 Python 中的线程并不是你所建议的那样毫无意义。它可以像在任何其他提供线程机制的语言中一样使用,即。让任务在等待资源等时产生 CPU 时间。我同意它是有限的,正如你在 GIL 中提到的那样,并且不允许你在多个内核上运行东西,但是,正如@zvone 所说,它在许多应用中都有使用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-30
      • 2019-01-29
      • 1970-01-01
      相关资源
      最近更新 更多