Hallo,
ich habe folgendes Problem: Ich habe Routinen die Im Thread ablaufen, ist innerhalb dieser Routine eine Benutzereingabe notwendig, geht meine CPU Auslastung auf 100%, tätige ich die Eingabe, läuft der Rechner wieder normal.
Meine Vermutung ist, das zu oft die Eingabe durch den Benutzer abgefragt wird.
Nun meine Frage gibt es eine Möglichkeit, dies zu lösen?
Benutze python 24 und wx.python.
Danke und ein schönes Wochenende.
Erforderliche Benutzereingaben legt den Rechner lahm
-
- User
- Beiträge: 6
- Registriert: Freitag 8. Januar 2010, 15:57
Der Tread
[/code]
Wenn ein Button kommt
Code: Alles auswählen
class worker_thread(threading.Thread, object):
"""!@brief Klasse, die die eigentliche Arbeitsroutine in einem separaten Thread
ausführt, damit die GUI bedienbar bleibt (für wxPython so erforderlich).
Neben dem eigentlichen Ausführen der Funktion in einem Thread werden
auch alle der Funktion übergebenen graphischen Elemente umgeleitet
und threadkonform verarbeitet, also mit wx.CallAfter()."""
def __init__(self, function, caller, finalEvent=None):
"""!@brief Konstruktor
@param[in] self Instanz dieser Klasse
@param[in] function Die auszuführende Funktion
@param[in] caller Struktur mit den betroffenen Klassen und Funktionen
@param[in] finalEvent hier kann eine Methode übergeben werden, welche
nach Ablauf der eigentlichen Funktion aufgerufen wird.
Typisches Beispiel: update_gui() muss am Ende des Threads
aufgerufen werden, dies darf aber nicht aus dem Thread
heraus geschehen"""
# Basisklasse initialisieren
threading.Thread.__init__(self)
## Die im Thread auszuführende Funktion
self.function = function
## @brief Struktur die der im Thread laufenden Funktion übergeben wird
##
## Darin enthalten sind Funktionen und Klassen mit Daten. Die Funktionen
## müssen noch threadsicher umgeleitet werden!
self.caller = caller
## Event, welches am Ende der run-Methode ausgelöst wird
self.finalEvent = finalEvent
# Alle GUI Funktionen auf den ThreadWrapper umleiten
self.caller.gui.redirect_all(mvpc_lib.ThreadWrapper)
# Den Task starten. Dieser Aufruf kehrt sofort zurück, da der Task ja
# parallel läuft. Der Task endet automatisch, wenn die oben übergebene
# Funktion zurückkehrt.
# self.start() ist in threading.Thread definiert und ruft automatisch
# die weiter unten zu findende Methode run() auf.
self.start()
def run(self):
"""!@brief Beim Start des Thread die übergebene Funktion mit den übergebenen
Parametern (caller) starten
@param[in] self Instanz dieser Klasse"""
# Der Task endet nach der Rückkehr aus self.function() automatisch,
# es sind keine weiteren Aktionen dafür notwendig!
self.function(self.caller)
# Die GUI-Funktionen wieder restaurieren. Das ist notwendig, da
# sie per Referenz übergeben und verändert wurden!!!
self.caller.gui.direct()
# Event an Methode knüpfen, welche nach Abschluss des Threads aufgerufen wird.
# Bei jeder Instanz wird dieses Event neu gekoppelt. Ansonsten müsste man das
# Event vor dem Threadstart von Hand setzen und nach Threadende wieder zurück-
# setzen. Die hätte den Nachteil, dass bei einem abgebrochenen Thread niemals
# der Fall "nach Threadende" erreicht wird und somit nicht zurückgesetzt wird.
# Das Koppeln findet in der run-Methode statt, weil sich sonst 2 gleichzeitig
# laufende worker_threads gegenseitig behindern könnten.
EVT_THREAD_DONE(working_area, self.finalEvent)
# Event auslösen, wenn die run-Methode zum Ende kommt
# Dies ist sinnvoll, weil man den Thread nicht mit join() beobachten kann.
# Somit kann man vor dem Aufrufen des Threads eine Methode bestimmen, welche
# nach Ablauf ausgeführt werden soll. Das bringt dann das selbe Ergebnis, wie
# ein Warten per join().
wx.PostEvent(working_area, WorkerThreadDoneEvent())]
Wenn ein Button kommt
Code: Alles auswählen
class ButtonClass:
"""!@brief Struktur, die Rückgabewerte für Buttons verwaltet"""
def __init__(self, text, buttonType, argument):
"""!@brief Konstruktor
@param[in] self Die Instanz der Klasse
@param[in] text Der Text auf dem Button
@param[in] buttonType Wert aus const.button_*
@param[in] argument notwendige Argumente für die jeweilige Aktion
Je nach Typ unterschiedlich. Beispiel: für
button_execute muss die Kommandozeile, die
ausgeführt werden soll angegeben werden"""
if isinstance(text, basestring):
## Der Wert
self.text = text
## Typ
self.type = buttonType
## das Argument
self.arg = argument
else:
raise _("Wrong Input")
def performAction(self, event):
"""!@brief Event, welcher beim Klick auf den Button ausgeführt wird
@param[in] self Die Instanz der Klasse
@param[in] event das Event"""
if self.type == const.button_execute:
# Als Argument muss bei dieser Aktion der aufzurufende Befehl als
# String übergeben werden
# direkt Starten geht nicht, dies muss in einem Thread geschehen,
# weil os.system() blockiert, bis der Befehl abgearbeitet ist
# Abgearbeitet ist dann, wenn das aufgerufene Programm beendet wird
# und den ReturnCode liefert
thread = redirection_thread(os.system, '"%s"' % self.arg)
thread.filename = self.arg
thread.start()
childAppThreads.append(thread)
-
- User
- Beiträge: 6
- Registriert: Freitag 8. Januar 2010, 15:57
Habe das Problem gefunden es gab eine Schleife in der nix gemacht wurde. Einen time.sleep eingebaut alles gut.
def ThreadWrapper(function, *argp, **argk):
def __handle(worker_var, function, *argp, **argk):
answer = [False, None]
wx.CallAfter(__handle, answer, function, *argp, **argk)
while answer[0] == False:
time.sleep(0.01)
return answer[1]
def ThreadWrapper(function, *argp, **argk):
def __handle(worker_var, function, *argp, **argk):
answer = [False, None]
wx.CallAfter(__handle, answer, function, *argp, **argk)
while answer[0] == False:
time.sleep(0.01)
return answer[1]
-
- User
- Beiträge: 6
- Registriert: Freitag 8. Januar 2010, 15:57
Ja als ich den Fehler gefunden habe, habe ich es auch gemerkt, das Progrmm wird halt langsam echt groß.