Search code examples
pythonmultithreadingwxpython

Python - Cannot join thread - No multiprocessing


I have this piece of code in my program. Where OnDone function is an event in a wxPython GUI. When I click the button DONE, the OnDone event fires up, which then does some functionality and starts the thread self.tstart - with target function StartEnable. This thread I want to join back using self.tStart.join(). However I am getting an error as follows:

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

I have not got this type of error before. Could any one of you guys tell me what I am missing here.

    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

I want to join the thread after the "if" condition has executed. Until them I want the thread to run.


Solution

  • Joining Is Waiting

    Joining a thread actually means waiting fo another thread to finish.

    So, in thread1, there can be code which says:

    thread2.join()
    

    That means "stop here and do not execute the next line of code until thread2 is finished".

    If you did (in thread1) the following, that would fail with the error from the question:

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

    Joining Is Not Stopping

    Calling thread2.join() does not cause thread2 to stop, nor even signal to it in any way that it should stop.

    A thread stops when its target function exits. Often, a thread is implemented as a loop which checks for a signal (a variable) which tells it to stop, e.g.

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

    Then, the way to stop the thread is to do:

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

    The Code from the Question

    That code already implements the stopping correctly with the break. The join should just be deleted.

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