Python/PySide: Wie kann ich Sie zerstören einen beendeten thread-Objekt?

Ich würde gerne implementieren Sie eine Taste zum beenden eines thread mit einem Prozess, es funktioniert aber nicht wie erwartet: ich kann nicht löschen das thread-Objekt. (EDIT: Die Referenz auf das thread-Objekt zu sein scheint gelöscht, aber die Signale sind nicht automatisch getrennt durch löschen des thread-Objekt, auf die ich zugreifen kann es trotzdem über das signal.)

Ich habe ein modul mit einer Klasse thread_worker und eine Funktion für komplexe Verarbeitung, die ausgeführt wird als Prozess:

from PySide.QtCore import *
from PySide.QtGui import *
import multiprocessing as mp
import time

# this function runs as a process
def complex_processing(queue):
    # do something
    ...

class thread_worker(QThread):
    message_signal = Signal(str)
    stop_thread_signal = Signal()

    def __init__(self, prozessID, sleepTime, parent=None):
        super(ThreadProzessWorker, self).__init__(parent)
        self.queue = mp.Queue()
        self.process = mp.Process(target=complex_processing, args=(self.queue,))
        self.timeStamp = int(time.time())

    def run(self):
        self.process.start()
        self.process.join()

    @Slot()
    def stop_process_and_thread(self):
        if self.isRunning():
            self.message_signal.emit("Thread %d is running!" % self.timeStamp)
            if self.process.is_alive():
                self.process.terminate()
                self.process.join()      
            self.stop_thread_signal.emit()   
            #self.terminate() # does it works at this place?       
        else:
            self.message_signal.emit("Thread %d is not running!" % self.timeStamp)

Ich habe zwei buttons in meine Anwendung zu erstellen/ausführen und beenden eines thread-Objekts.

...
...
# Buttons
self.button_start_thread = QPushButton("Start Thread")
self.button_start_thread.clicked.connect(self.start_thread)
self.button_stop_thread = QPushButton("Stop Thread")
...
...
@Slot()
def start_thread(self):
    self.new_thread = thread_worker(self)
    self.button_stop_thread.clicked.connect(self.new_thread.stop_process_and_thread)
    self.new_thread.stop_thread_signal.connect(self.stop_thread)
    self.new_thread.message_signal.connect(self.print_message)
....
....
@Slot()
def stop_thread(self):
    self.new_thread.terminate()
    #self.button_stop_thread.disconnect(self.new_thread)
    del(self.new_thread)

@Slot(str)
def print_message(self, message):
    print(message)
...
...

Wenn ich start und stop der ersten thread - es funktioniert einwandfrei und beenden, aber wenn ich klick auf den "Stop" -Taste erneut, wird die Ausgabe:

Thread 1422117088 is not running!

Ich verstehe es nicht: das Objekt self.new_thread gelöscht wird del(self.new_thread) oder nicht? Wie kann ich auf dieses Objekt, wenn es gelöscht wurde? Wenn ich starten und beenden und wieder einen neuen thread, der Ausgang ist:

Thread 1422117088 is not running!  # not expected, the thread object is deleted!
Thread 1422117211 is running!      # expected

Nun weiß ich es wieder (start und Stopp), die Ausgabe ist:

Thread 1422117088 is not running!   # not expected, the thread object is deleted!
Thread 1422117211 is not running!   # not expected, the thread object is deleted!
Thread 1422117471 is running!       # expected

und so weiter...

Erste Frage:
Ich verstehe nicht, warum die alten threads werden nicht gelöscht? Warum kann ich auf Sie zugreifen? Ich denke, es ist nicht gut: meine Anwendung stürzt ab, irgendwann, wenn es zu viele threads (nicht gelöschte Objekte) in den hintergrund.

Zweite Frage:
Ich dont zu verstehen, warum die Signale nicht getrennt, wenn ich ein Objekt löschen self.new_thread? Ich will nicht zu trennen, die Signale manuell: wenn ich viele Signale kann ich vergessen, zu trennen, einige Signale.

Dritte Frage:
Ich wähle diesen Weg, um zu stoppen, einen thread mit einem Prozess. Gibt es eine andere Möglichkeit das besser zu tun?

UPDATE:

Den thread-Objekt wird zerstört werden:

del(self.new_thread)
print(self.new_thread)
Output: AttributeError: 'MainWindow' object has no attribute 'new_thread'

Aber meine Signale sind nicht getrennt!? Hier beschrieben wird: "Ein signal-slot-Verbindung entfernt wird, wenn einer der beiden beteiligten Objekte sind zerstört." Es funktioniert nicht in meinem code.

Letzter Schuss... Entfernen print(self.new_thread), oder legen Sie Sie in einem try-except-Klausel
Ich habe nicht print(self.new_thread) in meinem code nun, das war nur um zu überprüfen, ob das Objekt gelöscht wird. Wir sehen, dass die Referenz - self.new_thread gelöscht wird, aber nicht das Objekt.

InformationsquelleAutor Igor | 2015-01-24

Schreibe einen Kommentar