multiprocessing mit einem GUI Toolkit

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
anogayales
User
Beiträge: 456
Registriert: Mittwoch 15. April 2009, 14:11

Hi Community,

ich arbeite mich grade in multiprocessing ein und bin auf ein Problem gestoßen. Ich starte aus einer GUI einen separaten Arbeiterthread aus diesem wiederum möchte ich Prozesse spawnen, die mir bei einer berechnung helfen. Leider klappt das ganze so nicht in Qt. Ich kann schlecht einschätzen ob es an Qt liegt oder einfach an einem generellen Problem, deswegen poste ich es mal im allgemeinen Forum.

Hier mein Minimalbeispiel, das das Problem darstellt:

Code: Alles auswählen

import sys, time, multiprocessing
from PyQt4 import QtGui, QtCore

forest_reference = []

def start():
    forest = RunForestRun()
    forest_reference.append(forest)
    forest.start()
    
app = QtGui.QApplication(sys.argv)

widget = QtGui.QWidget()
button = QtGui.QPushButton("Spawn Forest!")
layout = QtGui.QVBoxLayout()
widget.setLayout(layout)
layout.addWidget(button)
widget.resize(250, 150)
widget.setWindowTitle('simple')
widget.show()
button.clicked.connect(start)


def heavy_calculation(input):    
    time.sleep(1)
    print input*2
    return input*2


class RunForestRun(QtCore.QThread):
    def __init__(self):
        QtCore.QThread.__init__(self)
        
    def run(self):
        for i in range(4):
            print i
            time.sleep(0.5)
            

        p = multiprocessing.Pool()
        result = p.map(heavy_calculation, range(20))
        print result


if __name__ == "__main__":
    sys.exit(app.exec_())
Es wäre nett wenn ihr euch das ganze mal angucken könntet. Ist ja nicht überkompliziert. Bei dem ganzen öffnen sich nachdem der Thread fertiggezählt hat eine vielzahl an fenstern, was wohl an dem app.exec_ liegt. Wie kann ich das ganze in den griff kriegen?

Grüße,
anogayales
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Es liegt am GUI-Toolkit. Diese vertragen sich i.A. nicht gut mit den Standard Thread-Komponenten. Greife daher auf die von Qt mitgelieferten Klassen zurück. Ich verweise mal auf diesen "Thread" :-D
http://www.python-forum.de/viewtopic.php?f=11&t=24036
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
anogayales
User
Beiträge: 456
Registriert: Mittwoch 15. April 2009, 14:11

Ich benutze ja schon QtCore.QThread. Ein QProcess gibt es zwar, aber ich seh nicht so ganz wie ich es als multiprocessing Modulersatz benutzen könnte.

Grüße,
anogayales
lunar

Ich kann mit dem gezeigten Quelltext unter Linux kein Problem nachvollziehen. Welches System verwendest Du denn?

Ferner möchte ich fragen, ob es Dir tatsächlich um eine echte Parallelisierung geht, bzw. ob diese tatsächlich nötig ist, oder ob Du nur das Blockieren der GUI vermeiden möchtest. In letzterem Falle ist multiprocessing reichlich überflüssig.
BlackJack

Der reST-Editor von Roberto Alsina hat eine Qt-GUI und verwendet `multiprocessing`: http://code.google.com/p/rst2pdf/source ... ui/main.py

Es muss also grundsätzlich irgendwie gehen.
anogayales
User
Beiträge: 456
Registriert: Mittwoch 15. April 2009, 14:11

Ja, ich möchte einen Haufen Daten abarbeiten. Das ganze läuft ja bereits in einem Arbeiterthread (QThread). Um eine echte Parallelisierung zu erreichen brauch in ja aber, wenn ich CPython benutzte, Prozesse.

Liegt wahrscheinlich an Windows, da Windows ja kein fork kann und somit die Hauptdatei aufrufen muss.

Es wäre nett, wenn mir jemand helfen könnte.

Den Stacktrace den ich übrigens bekomm ist:

Code: Alles auswählen

Exception in thread Thread-3:
Traceback (most recent call last):
  File "C:\Python26\lib\threading.py", line 532, in __bootstrap_inner
    self.run()
  File "C:\Python26\lib\threading.py", line 484, in run
    self.__target(*self.__args, **self.__kwargs)
  File "C:\Python26\lib\multiprocessing\pool.py", line 225, in _handle_tasks
    put(task)
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
Grüße,
anogayales
Antworten