I would like to implement a button to stop a thread with a process, it works but not as expected: i can't delete the thread object. (EDIT: The reference to the thread object seems to be deleted, but the signals are not disconnected automatically by deleting the thread object, i can access it anyway via the signal.)
I have a modul with a class thread_worker and a function for complex processing which is running as process:
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)
I have two buttons in my application to create/run and terminate a thread object.
...
...
# 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)
...
...
If i start and stop the first thread - it works fine and terminate, but if i klick on the 'Stop'-Button again the output is:
Thread 1422117088 is not running!
I don't understand it: the object self.new_thread
is deleted by del(self.new_thread)
or not? How can i access this object if it was deleted? If i start and stop again a new thread, the output is:
Thread 1422117088 is not running! # not expected, the thread object is deleted!
Thread 1422117211 is running! # expected
Now i do it again (start and stop), the output is:
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
and so on...
First question: I don't understand why the old threads are not deleted? Why i can access them? I think it is not good: my application crashes at some point, if there are too many threads (not deleted objects) in the background.
Second question:
I dont't understand why the signals are not disconnected if i delete the object self.new_thread
? I don't want to disconnect the signals manually: if i have many signals i can forgot to disconnect some signals.
Third question: I choose this way to stop a thread with one process. Is there another way to do this better?
UPDATE:
The thread object appears to be destroyed:
del(self.new_thread)
print(self.new_thread)
Output: AttributeError: 'MainWindow' object has no attribute 'new_thread'
But my signals are not disconnected!? Here is described that: "A signal-slot connection is removed when either of the objects involved are destroyed." It does not work in my code.