Cameron Finnie
Cameron Finnie

Reputation: 35

Infinite loops in Python threads

So I have two python threads running from inside a class. I have checked using

threading.active_count()

and it says both threads are running. The first thread includes a tkinter window which works fine. The second thread I am using as an event manager for the first window, which also works okay by itself. However, when I run the second thread alongside the first thread, the first thread does not work, ie. the window does not appear. This is even if the first thread is executed first. When I remove the infinite loop from the second thread, the first thread works again, can anyone explain this to me? Here is the class:

class Quiz(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)


    def show(self, question):
        self.question = quiz[question][0]
        self.correct = quiz[question][1]
        self.incorrectA = quiz[question][2]
        self.incorrectB = quiz[question][3]
        self.ref = quiz[question][4]
        questionDisplay.config(text=self.question)
        correctButton = "answer" + str(self.ref[0])
        eval(correctButton).config(text=self.correct, command=lambda : check(True))
        incorrect1 = "answer" + str(self.ref[1])
        eval(incorrect1).config(text=self.incorrectA, command= lambda : check(False))
        incorrect2 = "answer" + str(self.ref[2])
        eval(incorrect2).config(text=self.incorrectB, command= lambda : check(False))
        return self.correct

    def run(self):
        print("thread started")
        print(threading.active_count())

        while True:
            print(questionQueue.qsize())
            if questionQueue.qsize() >= 1:
                pass

            else:
                pass
            print("looped")

Thanks

Upvotes: 2

Views: 235

Answers (1)

Roland Smith
Roland Smith

Reputation: 43495

From the code as currently shown it is not obvious where the problem lies. But keep the following in mind;

Tk is event-driven like basically all GUI toolkits. So for the GUI to work you need to run Tk's mainloop. The only pieces of your code that it runs in the main loop are the various callbacks attached to things like buttons, menus and timers.

Like most GUI toolkits Tk isn't thread-safe because of the overhead that would require. To keep it working properly, you should only call Tk functions and methods from one thread.

Python's threads are operating system threads. This means they are subject to operating system scheduling. And the OS sometimes gives more time to threads that are busy. So if a thread that is spinning in a busy-loop is pre-empted (as is done regularly), chances are that it ends up being run again instead of the GUI thread.

Upvotes: 1

Related Questions