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)
Geht ned mit luks_open
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.
Luna
r 
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
