Probleme mit multiprocessing-Modul unter Windows

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
philistion
User
Beiträge: 108
Registriert: Sonntag 7. Februar 2010, 14:16

Hallo,

ich habe ein Problem mit dem Modul [mod]multiprocessing[/mod]. Allerdings tritt dieses nur unter Windows auf, unter Linux funktioniert mein Code problemlos.

Ich beschreibe nun kurz was ich mache, vielleicht findet sich darin schon der eine oder andere Fehler.

In der Init Funktion der PyQt-Fensterklasse (QMainWindow), in welcher die Oberfläche erstellt wird, starte ich auch die anderen Prozesse bzw. koordiniere sie.

Dort mache ich erstmal folgendes:

Code: Alles auswählen

...
from multiprocessing import (Manager,  log_to_stderr)
...

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__(None)
        ...
        self.manager = Manager()
        self.databaseQueue = self.manager.Queue()

        ...

        self.databaseProc = DataProcess(self.databaseQueue)
        self.snifferProc = SnifferProcess(self.databaseQueue)

        ...
Ich erstelle eine Manager-Klasse, welche das pickeln erledigen sollte, und verwende die von dort aus erstellte Queue zur Kommunikation zwischen den zwei Arbeitsprozessen. Danach werden die Prozesse erstellt, denen ich die Queue übergebe.

SnifferProcess liest nun vom Netzwerk Daten ein, verarbeitet sie und gibt sie anschließend in die Queue. DataProcess holt sie sich aus der Queue und fügt sie dann in eine Datenbank ein.

Der Code des Prozesses sieht folgendermaßen aus:

Code: Alles auswählen

from multiprocessing import (Process)

class DataProcess(Process):
    def __init__(self, dbqueue):
        Process.__init__(self)
        self.dbqueue = dbqueue        
        ...
    def run(self):
        for data in iter(self.dbqueue.get,  self.sentinel):
            # Daten in Datenbank einfügen , self.sentinel ist nur die Abbruchbedingung
            ...
Der Sniffer-Prozess sieht von der Struktur her ähnlich aus, liest periodisch Daten aus dem Netzwerk aus und fügt diese dann mit

Code: Alles auswählen

self.dbqueue.put(daten)
in die Queue, welche dann vom DataProcess (siehe oben) abgeholt werden kann.

Um das Problem zu verstehen poste ich noch kurz meine Haupt-Pythondatei:

Code: Alles auswählen

...
from multiprocessing import freeze_support

def main():
    freeze_support()

    print("Qt Version: %s" % QT_VERSION_STR)
    print("PyQt Version: %s" % PYQT_VERSION_STR)

    app = QApplication(argv)
    app.setApplicationName("xy")

    form = MainWindow()
    form.show()
    app.exec_()

main()
Unter Linux funktioniert alles perfekt, doch unter Windows wird nach Starten der Applikation die Qt- und die PyQt-Version unendlich oft hintereinander ausgegeben und die eigentliche Oberfläche wird gar nicht erst erstellt. Für mich macht dies keinen Sinn, es kommt ja nur am Anfang des Hauptprogramms vor und alles was mit multiprocessing zu tun hat, kommt erst an späterer Stelle ins Spiel.

Vielleicht findet jemand eine Problemstelle oder hat gar so eine Situation schon mal erlebt.

Die Windows-Version unter der ich diese Software getestet habe, war übrigens Windows7 und ich verwende Python 2.6.

Da es sich hierbei nicht um ein Qt- sondern um ein allgemeines Python Problem ([mod]multiprocessing[/mod]) handelt, passt es m.E. am besten in Allgemeine Fragen.

Vielen Dank für die Hilfe schon mal im Voraus!

mfG
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

philistion hat geschrieben:Unter Linux funktioniert alles perfekt, doch unter Windows wird nach Starten der Applikation die Qt- und die PyQt-Version unendlich oft hintereinander ausgegeben und die eigentliche Oberfläche wird gar nicht erst erstellt. Für mich macht dies keinen Sinn, es kommt ja nur am Anfang des Hauptprogramms vor und alles was mit multiprocessing zu tun hat, kommt erst an späterer Stelle ins Spiel.

Vielleicht findet jemand eine Problemstelle oder hat gar so eine Situation schon mal erlebt.
Hast du diesen Teil der Dokumentation gelesen? In dem Codeschnippsel was du gepostet hast, machst du es genau so wie man es nicht tun sollte, daher könnte es sein dass das seltsame Verhalten daran liegt.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
philistion
User
Beiträge: 108
Registriert: Sonntag 7. Februar 2010, 14:16

Natürlich hab ich das gelesen, was meinst du denn genau?

Wenn du auf "Safe importing of main module" ansprichst. Das kommt doch in meinem Fall deswegen nicht zum tragen, weil ich die Haupt-Pythondatei nicht von irgendwo anders aus importiere. Und die Prozesse erstelle ich in der init-Routine der Klasse, sie werden somit definitiv nur einmal ausgeführt.

Diese Hauptdatei soll ja nicht von einem neuen Python-Interpreter gestartet werden, in diesem soll ja nur die abgeleitete Prozess-Klasse interpretiert werden, nicht aber das Hauptmodul.

Vielleicht kannst du näher erklären was ich deiner Meinung nach übersehen habe. Danke!
Zuletzt geändert von philistion am Sonntag 25. April 2010, 11:09, insgesamt 2-mal geändert.
Benutzeravatar
HerrHagen
User
Beiträge: 430
Registriert: Freitag 6. Juni 2008, 19:07

Kommt mir irgendwie bekannt vor. Ich weiß es nicht mehr genau, aber ich glaub das war die Lösung:
Füg mal ein

Code: Alles auswählen

if __name__ == "__main__":
ein vorm Starten von main() ein.
philistion
User
Beiträge: 108
Registriert: Sonntag 7. Februar 2010, 14:16

Danke für die Antworten.

Ist es denn wirklich so, dass bei diesem neu gespawnten Prozess immer auch die Haupt-Pythondatei mitausgeführt wird? Das wäre ja ziemlich unsinnig, oder?

// Edit: Es scheint zu funktionieren, vielen Dank! Trotzdem verstehe ich diese Verhaltensweise nicht wirklich. Warum ist dies notwendig?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

philistion hat geschrieben:Ist es denn wirklich so, dass bei diesem neu gespawnten Prozess immer auch die Haupt-Pythondatei mitausgeführt wird? Das wäre ja ziemlich unsinnig, oder?
Windows hat kein Fork also muss irgendein komplett neuer Prozess gestartet werden und aus diesem muss ja *irgendein* Modul importiert werden. Wenn dein Modul aber beim Import komische Sachen anfängt, kommt ``multiprocessing`` damit wohl nicht klar.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
philistion
User
Beiträge: 108
Registriert: Sonntag 7. Februar 2010, 14:16

Naja, aber das Haupt-Modul ist doch zur Ausführung des jeweiligen Prozesses überhaupt nicht notwendig, es ist ja alles im spezifischen Modul, welches gestartet wird definiert. Alle Includes usw, und ich binde nirgendwo wieder das Hauptprogramm ein.

Kann mir jemand einen vernünftigen Grund sagen, warum der neue Interpreter beim Start ausgerechnet das Hauptfile interpretiert?

Trotzdem Danke für die Hilfe!
Antworten