2016-05-15 21 views
2

So habe ich zwei Python-Threads innerhalb einer Klasse ausgeführt. Ich habe überprüft mitUnendliche Schleifen in Python-Threads

threading.active_count() 

und es sagt, dass beide Threads ausgeführt werden. Der erste Thread enthält ein tkinter-Fenster, das gut funktioniert. Der zweite Thread, den ich als Event-Manager für das erste Fenster verwende, funktioniert auch von selbst. Wenn ich jedoch den zweiten Thread neben dem ersten Thread ausführe, funktioniert der erste Thread nicht, d. Das Fenster wird nicht angezeigt. Dies ist auch dann der Fall, wenn der erste Thread zuerst ausgeführt wird. Wenn ich die Endlosschleife aus dem zweiten Thread entferne, funktioniert der erste Thread wieder, kann mir das jemand erklären? Hier ist die Klasse:

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") 

Dank

+0

Wenn jemand mehr von dem Code braucht, sagen Sie mir einfach –

+0

Quick-Punkt: Da Ihre Klasse "__init__" von "threading.thread" erben wird, wenn Sie es nicht definieren, können Sie diese Methode auch aus Ihrer Definition weglassen. – holdenweb

+0

Im Allgemeinen unterstützt tkinter keine Threads. Dies kann erfolgen, solange die GUI nur im Hauptthread ausgeführt wird und alle Interaktionen mit anderen durch Sperren ausgeführt werden, um den gleichzeitigen Zugriff auf Daten und/oder threadsichere Datenstrukturen wie Warteschlangen zu steuern. – martineau

Antwort

1

Aus dem Code wie zur Zeit gezeigt, dass es nicht offensichtlich ist, wo das Problem liegt. Aber behalte Folgendes im Hinterkopf;

Tk ist ereignisgesteuert wie alle GUI Toolkits. Damit die GUI funktioniert, müssen Sie Tk's mainloop ausführen. Die einzigen Teile Ihres Codes, die in der Hauptschleife ausgeführt werden, sind die verschiedenen Rückrufe, die mit Dingen wie Buttons, Menüs und Timern verbunden sind.

Wie die meisten GUI-Toolkits ist Tk nicht Thread-sicher, da der Overhead dies erfordert. Damit es richtig funktioniert, sollten Sie nur Tk-Funktionen und Methoden von einen Thread aufrufen.

Python-Threads sind Betriebssystem-Threads. Dies bedeutet, dass sie der Betriebssystemplanung unterliegen. Und das OS gibt manchmal mehr Zeit für Threads, die beschäftigt sind. Wenn also ein Thread, der sich in einer Busy-Schleife dreht, vorprogrammiert ist (wie es regelmäßig geschieht), ist es möglich, dass er statt des GUI-Threads erneut ausgeführt wird.

+0

Wäre ich in der Lage, die Fensterkonstruktion dem selben Faden wie die show() Methode hinzuzufügen? Oder könnte es in der __init __() Methode gemacht werden? Ich glaube nicht, dass ich die Fensterkonstruktion der gleichen Methode wie show() hinzufügen kann, da show() Aspekte des Fensters ändert und wahrscheinlich benötigt wird, um den Code zu schreiben. –

+0

Es gibt wenig, wenn überhaupt einen Grund zu bauen eine Klasse dafür sowieso. Halte es einfach. Erstellen Sie eine Funktion, die im zweiten Thread ausgeführt werden soll, und erstellen Sie die Widgets, und führen Sie im Hauptthread den Befehl 'mainloop' aus. –