wizard.Destroy() hängt Programm auf

Plattformunabhängige GUIs mit wxWidgets.
Antworten
seppi
User
Beiträge: 12
Registriert: Dienstag 30. August 2011, 13:20

Hallo Zusammen,
ich stehe derzeit vor einem größeren Problem. Und zwar bin ich seit 3 Tagen auf der Suche nach der Ursache gewesen. Jetzt meine ich die Ursache gefunden zu haben, es scheint der Aufruf von wizard.Destroy() zu sein.

Zum Programm:
Mein Programm unterstützt das mehrere Prozesse gestartet werden, dabei wird ein multiprocessing.Pool erstellt und Tasks auf diesen Pool aufgeteilt. Um ein funktionierendes Logging zu erreichen, habe ich mich dazu entschieden eine Manager.Queue() zwischen MainProzess und den ChildProzessen zu erstellen, auf welche die childs schreiben können und der Main Prozess die logs lesen und verarbeiten kann.
Dazu läuft auf dem MainProzess ein QueueListener-Thread, welcher ununterbrochen auf neue Botschaften abfragt.

Zum Problem:
Das Problem ereignet sich wie folgt: Wenn ich während der Laufzeit mein Wizard aufgerufen habe und danach mein Programm schließen will, hängt sich der MainProzess bei wizard.Destroy() auf. (Ohne Traceback oder sonstiges)
Wenn kein Wizard während der Laufzeit geöffnet wurde, beendet sich das Programm und alle unterprozesse, wie gewünscht.

Was kann zu diesem Problem führen? Ich habe an der Terminierung und Erstellung des Wizards seit der Umstellung auf multiprocessing keine größeren Veränderungen vorgenommen - dennoch war es früher möglich das Programm auch nach Aufruf des Wizards ordnungsgemäß zu beenden.
Desweiteren habe ich die benutzten Aufrufe in einem Testmodul ausprobiert, hier ließ sich alles schließen/öffnen.

Ich bin über jeden Ratschlag sehr dankbar!
Benutzeravatar
ocoal
User
Beiträge: 32
Registriert: Mittwoch 20. Juli 2011, 22:44

Hallo,

kannst Du ein paar Rahmendaten zu Deiner Umgebung auflisten?

Wie z.B.
- Python-Version
- wxPython-Version
- Betriebssystem

-Colin-
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Und uns deinen Code zeigen? (Zumindest die relevanten Teile)
the more they change the more they stay the same
seppi
User
Beiträge: 12
Registriert: Dienstag 30. August 2011, 13:20

@Dav1d
Aufruf des Wizards:

Code: Alles auswählen

        # Neues Wizard-Objekt erzeugen
        self.wiz = Wizard.Wizard(self, 'Erste Wizardseite...', (700,400))
        # Startet den Wizard mit der Seite 1
        if self.wiz.wizard.RunWizard(self.wiz.wizardPages[0]):
            print 'Wizard was finished'           
            savedir = x.config[x.SAVEDIR]
            resultFile = x.xml.config[x.P1][x.P1C1].split("\\")[-1]
            self.panelLeft.setQueueElement(resultFile , doJob, x.xml, savedir)
        else:
            print 'Wizard was cancelled'  
Hinzufügen eines Jobs:

Code: Alles auswählen

self.sharedEvents[queueElem] = {}
        
        progressTicks = MANAGER.Value("i", 0)
        pauseEvent = MANAGER.Event()
        abortEvent= MANAGER.Event()
        finishedEvent = MANAGER.Event()
        
        self.sharedEvents[queueElem]["pause"] = pauseEvent
        self.sharedEvents[queueElem]["abort"] = abortEvent
        self.sharedEvents[queueElem]["finished"] = finishedEvent
        
        self.apply_async(job, (args, progressTicks, pauseEvent, abortEvent, finishedEvent))
        self.progresssListener.addProgress(progressTicks, queueElem, finishedEvent)
@ocoal
Python 2.7.2
wxPython 2.8
OS WindowsXP
deets

Was mir dazu kurz einfaellt: wann rufst du multiprocessing auf? Es kann durchaus sein, dass sich Bibliotheken verklemmen, wenn ein Fork oder CreateProcess zu spaet kommt. Ich wuerde dir darum raten, deine Worker-Prozesse so frueh wie moeglich zu erzeugen, bevor du GUI und Co hochziehst. Vielleicht loest das dein Problem.
seppi
User
Beiträge: 12
Registriert: Dienstag 30. August 2011, 13:20

Also der Pool wird zu beginn des Programms erstellt. Die Worker starten dann ja meines Wissens automatisch und warten auf Jobs die ich "apply"/zuweise. Das Zuweisen kann erst nach Beenden des Wizards geschehen, da für das Zuweisen Benutzereingaben notwendig sind.

Hier noch die Main():

Code: Alles auswählen

   
def __setupProcesses():
        Processing.MANAGER = Processing.Manager()
        Processing.LOGGINGQUEUE = Processing.MANAGER.Queue()
        Processing.PROCESSPOOL = Processing.ProcessPool()
    
    
if __name__ == '__main__':
    multiprocessing.freeze_support()
    __setupProcesses()  
    app = App(False) 
    app.MainLoop()
Antworten