Seite 1 von 1

QThread blockt GUI bei 100% CPU last :/

Verfasst: Montag 27. Dezember 2010, 19:01
von AngelusNoctis
Hi

Weiss jemand wie man QThread dazu bewegt die GUI (Progressbar und MainWindow) nicht zu blocken auch wenn QThread ne 100% CPU Last erzeugt?

Habs schon mit wait() und der priorität versucht aber sobald der Thread läuft und die CPU auf 100% knallt bleibt der ProgressBarDialog und das MainWindow hängen :/

Kann jemand helfen?

Code: Alles auswählen

    def onButtonApply(self):
        self.progressBar = QtGui.QProgressDialog(self, QtCore.Qt.FramelessWindowHint) #QtCore.Qt.X11BypassWindowManagerHint)
        self.progressBar.setRange(0,0)
        self.progressBar.setLabelText(self.tr('Please wait'))
        self.progressBar.setCancelButton(None)        
        self.progressBar.show()
        
        self.thread = Thread(str(self.lineDevice.text()), str(self.lineMount.text()), str(self.comboBox.currentText()), str(self.linePassphrase.text()), str(self.lineKeyfile.text()))
        self.thread.start()
        self.connect(self.thread,  QtCore.SIGNAL('finished()'), self.onFinish)

class Thread(QtCore.QThread):    
    def __init__(self, device, mountpoint, fs, passphrase, key_file):
        QtCore.QThread.__init__(self)
        self.device = device
        self.mountpoint = mountpoint
        self.fs = fs
        self.passphrase = passphrase
        self.key_file = key_file

    def run(self):
        if os.path.isfile(self.device):
            lo = addLoop(self.device)
            luksID= 'luks-' + luks_uuid(lo[1])
            luks_open(lo[1], luksID, self.passphrase, self.key_file)
            mountDevice(self.mountpoint, '/dev/mapper/' + luksID, self.fs)
        else:
            luksID = 'luks-' + luks_uuid(self.device)
            luks_open(self.device, luksID, self.passphrase, self.key_file)
            mountDevice(self.mountpoint, '/dev/mapper/' + luksID, self.fs)

Re: QThread blockt GUI bei 100% CPU last :/

Verfasst: Montag 27. Dezember 2010, 20:00
von lunar
Wenn die graphische Oberfläche hängen bleibt, ohne dass das ganze System abstürzt, dann ist aller Wahrscheinlichkeit nach ein Fehler in Deinem Quelltext, der dazu führt, dass der rechenintensive Abschnitt gar nicht in einem separaten Thread läuft. Ob das tatsächlich der Fall ist, und wo in diesem Fall der Fehler genau liegt, kann man Dir nicht sagen, solange Du nur Stückchen aus Deinem Programm zeigst. Du glaubst doch nicht wirklich, dass jemand mit diesem kurzen Stücken irgendeinen essentiellen Fehler in Deinem Programm aufdecken kann? Zumal in diesem Quelltext so direkt auch nichts zu erkennen ist, was die CPU tatsächlich voll auslasten könnte.

Wenn Du Hilfe möchtest, dann musst Du Dir schon die Mühe einer anständigen, detaillierten und mit möglichst kleinem, aber aussagekräftigem Quelltext hinterlegten Problembeschreibung machen.

Re: QThread blockt GUI bei 100% CPU last :/

Verfasst: Montag 27. Dezember 2010, 20:18
von AngelusNoctis
Der Teil der die CPU hochjagt ist luks_open.

Die Funktion luks_open wurde von den Red Hat Devs geschrieben, ich hab den Teil 1:1 von der crypto.py aus dem Anaconda Installer.

Die Funktion nutzt python-cryptsetup das Binding zu cryptsetup was wiederum beides von den Red Hat Devs stammt.

Die C implementierung von cryptsetup jagt die CPU auch auf 100% wenn man es über die Konsole nutzt, nur dachte ich wenn das ganze in nem extra Thread (vorallem bei SMP System) läuft sollte die GUI nicht blockieren.

Sollte doch irgendwie möglich sein?

http://git.fedorahosted.org/git/?p=anac ... adf00b658f

Code: Alles auswählen

def luks_open(device, name, passphrase=None, key_file=None):
    cs = CryptSetup(yesDialog = askyes, logFunc = dolog)
    key_file_unlink = False

    if passphrase:
        key_file = cs.prepare_passphrase_file(passphrase)
        key_file_unlink = True
    elif key_file and os.path.isfile(key_file):
        pass
    else:
        raise ValueError("luks_open requires either a passphrase or a key file")

    rc = cs.luksOpen(device = device, name = name, keyfile = key_file)
    if key_file_unlink: os.unlink(key_file)
    if rc:
        raise CryptoError("luks_open failed for %s (%s)" % (device, name))
Hier noch python-cryptsetup http://git.fedorahosted.org/git/?p=pyth ... tsetup.git


Hoff das hilft weiter

Re: QThread blockt GUI bei 100% CPU last :/

Verfasst: Montag 27. Dezember 2010, 20:49
von BlackJack
@AngelusNoctis: Das dürfte wenig mit der CPU-Last, noch irgendwelchen Prioritäten zu tun haben. Wenn die GUI blockiert, dann hat man in der Regel etwas bei der Verwendung mit Threads falsch gemacht. In diesem Fall sieht aber (fast) alles richtig aus, also ist die Frage was genau mit "hängen" gemeint ist?

Die Reihenfolge von Thread starten und Signal verbinden ist ungünstig, weil es so passieren kann, dass der Thread fertig ist, bevor das Verbinden des Signals passiert ist.

Re: QThread blockt GUI bei 100% CPU last :/

Verfasst: Montag 27. Dezember 2010, 20:59
von AngelusNoctis
@BlackJack

Das Hängen äussert sich folgender massen:

1) ProgressBar erscheint nicht sofort sondern erst nach dem "luks_open" abgeschlossen wurde
2) Nix reagiert mehr bis "luks_open" abgeschlossen wird
3) Beim verschieben des Dialoges wird der Dialog nicht neu gezeichnet und das ganze ist grau solang "luks_open" nicht abgeschlossen ist


Am signal liegts ned, aber ich werds nachher noch verschieben bzw vor den thread start.

Re: QThread blockt GUI bei 100% CPU last :/

Verfasst: Montag 27. Dezember 2010, 21:05
von lunar
Die Anmerkungen über die Signale hatte mit dem Problem selbst nichts zu tun, sondern war allgemeiner Natur, und sollte natürlich beachtet werden, denn BlackJack hat auch in diesem Fall recht, ich hätte das auch angemerkt, wenn es mir aufgefallen wäre.

Wie gesagt, "luks_open" läuft wahrscheinlich nicht in einem separaten Thread. Aber Du kannst testen, ob es an "luks_open" und dessen CPU-Last liegt, indem Du es durch eine blockierende Operation ohne große CPU-Last ersetzt (e.g. "time.sleep(3600)"). Blockiert die GUI dann immer noch, liegt es ganz offensichtlich nicht an "luks_open()", was uns zurück zur bereits geäußerten Vermutung führt.

Re: QThread blockt GUI bei 100% CPU last :/

Verfasst: Montag 27. Dezember 2010, 21:30
von AngelusNoctis
@lunar

Also ich hab jetzt mal time.sleep(3600) reingeknallt und die GUI hängt nicht, der ProgressBar erscheint sofort...

Hab jetzt mal ein Bild zum "hängen" gemacht, man sieht schön das der ProgressBarDialog einfach nur grau ist und sich garnix tut, bis eben luks_open fertig ist...

Code: Alles auswählen

class Thread(QtCore.QThread):    
    def __init__(self, device, mountpoint, fs, passphrase, key_file):
        QtCore.QThread.__init__(self)
        self.device = device
        self.mountpoint = mountpoint
        self.fs = fs
        self.passphrase = passphrase
        self.key_file = key_file
        
    def run(self):
        time.sleep(3600)
#        if os.path.isfile(self.device):
#            lo = addLoop(self.device)
#            luksID= 'luks-' + luks_uuid(lo[1])
#            luks_open(lo[1], luksID, self.passphrase, self.key_file)
#            mountDevice(self.mountpoint, '/dev/mapper/' + luksID, self.fs)
#        else:
#            luksID = 'luks-' + luks_uuid(self.device)
#            luks_open(self.device, luksID, self.passphrase, self.key_file)
#            mountDevice(self.mountpoint, '/dev/mapper/' + luksID, self.fs)


Geht mit time.sleep(3600)

Bild

Geht ned mit luks_open

Bild




Theme Unterschiede wegen root/user...

Re: QThread blockt GUI bei 100% CPU last :/

Verfasst: Donnerstag 30. Dezember 2010, 15:25
von AngelusNoctis
Hat echt keiner ne Idee? :(

Am GIL von Python 2 kanns ned liegen? oO

Re: QThread blockt GUI bei 100% CPU last :/

Verfasst: Donnerstag 30. Dezember 2010, 15:59
von lunar
@AngelusNoctis: Wenn ich eine Idee hätte, die über das bereits gesagte hinausgeht, hätte ich Dich schon nicht im Dunkeln gelassen ;)

Re: QThread blockt GUI bei 100% CPU last :/

Verfasst: Freitag 31. Dezember 2010, 12:58
von AngelusNoctis
@Luna k :)


Ich glaub ich schreib mal den Dialog 1:1 in C++ und guck ob der in C++ auch hängt, wenn nicht liegt es wohl an python/pyqt/pycryptsetup?

Re: QThread blockt GUI bei 100% CPU last :/

Verfasst: Freitag 31. Dezember 2010, 13:23
von lunar
@AngelusNoctis: Es schadet bestimmt auch nicht, den Entwicklern dieses Python-Moduls diesen Fall zu schildern. Vielleicht handelt es sich ja um ein bekanntes Problem. Zudem wissen diese Entwickler am besten, wie ihr Modul funktioniert, und wo es möglicherweise mit PyQt in Konflikt treten könnte.

Lunar ;)

Re: QThread blockt GUI bei 100% CPU last :/

Verfasst: Freitag 31. Dezember 2010, 15:55
von AngelusNoctis
@Lunar

Stimmt, dazu müsste man aber am besten wissen obs wirklich nur unter PyQt auftritt ^^

Davon abgesehen wollte ich mal gucken ob ich pycryptsetup dazu bewegen kann das es mit python 3 läuft und die diff dann übergeben :)