我有一个模块,其中包含一个名为thread_worker的类和一个用于复杂处理的函数,该函数正在作为进程运行:
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)
我的应用程序有两个按钮,一个是创建/运行线程对象,另一个是终止线程对象。
...
...
# 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)
...
...
如果我启动并停止第一个线程-它可以正常工作并终止,但是如果我再次点击“停止”按钮,输出结果如下:
Thread 1422117088 is not running!
我不太明白:对象 self.new_thread
是被 del(self.new_thread)
删除了吗?如果它已经被删除了,我该如何访问这个对象呢?如果我再次启动和停止一个新线程,输出会是什么:
Thread 1422117088 is not running! # not expected, the thread object is deleted!
Thread 1422117211 is running! # expected
现在我再次执行它(启动和停止),输出如下:
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
第一个问题: 我不明白为什么旧的线程没有被删除?为什么我还可以访问它们?我认为这不好:如果后台有太多的线程(未删除的对象),我的应用程序会在某些时候崩溃。
第二个问题:
我不明白为什么如果我删除self.new_thread
对象,信号不会被断开连接?我不想手动断开信号的连接:如果我有很多信号,我可能会忘记断开一些信号的连接。
第三个问题: 我选择使用这种方式来停止一个进程的线程。是否有更好的方法来做到这一点?
更新:
线程对象似乎已被销毁:
del(self.new_thread)
print(self.new_thread)
Output: AttributeError: 'MainWindow' object has no attribute 'new_thread'
但我的信号没有被断开!? 这里 描述了: "当涉及的任一对象被销毁时,信号槽连接将被删除。" 但在我的代码中它不起作用。
print(self.new_thread)
,那只是为了检查对象是否被删除。我们看到,引用self.new_thread
被删除了,但对象并没有被删除。 - Igor