1 回答

TA貢獻(xiàn)1155條經(jīng)驗(yàn) 獲得超0個(gè)贊
好吧,現(xiàn)在我已經(jīng)知道問題出在哪里了。當(dāng)我終止進(jìn)程時(shí)self.__net.terminate()仍然存在僵尸進(jìn)程,為什么我認(rèn)為這不是正確的解決方案。
僵尸進(jìn)程是由 QRunnable 引起的,它不會(huì)終止,因?yàn)樗诘却舆M(jìn)程在隊(duì)列中發(fā)送信號(hào)。
因此,我需要一個(gè)自定義的“終止”函數(shù),它調(diào)用 Terminate() 并向 QRunnable 發(fā)送一個(gè)信號(hào),表明該過程已完成。這樣,所有進(jìn)程和線程都會(huì)相應(yīng)終止,并且不會(huì)留下任何僵尸進(jìn)程。
import tensorflow as tf
from sys import exit, argv
from multiprocessing import Process, Queue
from PyQt5.QtWidgets import QPushButton, QApplication, QHBoxLayout, QWidget, QLabel
from PyQt5.QtCore import QRunnable, QObject, pyqtSignal, QThreadPool
class Window(QWidget):
def __init__(self):
QWidget.__init__(self)
self.__btn_run = QPushButton("Start")
self.__btn_stp = QPushButton("Stop")
self.__label = QLabel("Idle")
self.__runner = Runner()
self.__pool = QThreadPool.globalInstance()
self.__btn_run.clicked.connect(self.__run_net)
self.__btn_stp.clicked.connect(self.__stp_net)
self.__runner.signals.finished.connect(self.__on_finished)
self.__btn_stp.setDisabled(True)
self.setLayout(QHBoxLayout())
self.layout().addWidget(self.__btn_run)
self.layout().addWidget(self.__btn_stp)
self.layout().addWidget(self.__label)
def __run_net(self):
self.__btn_run.setDisabled(True)
self.__btn_stp.setEnabled(True)
self.__label.setText("Running")
self.__pool.start(self.__runner)
def __stp_net(self):
self.__runner.close()
# What to do here?
def __on_finished(self):
self.__btn_run.setEnabled(True)
self.__btn_stp.setDisabled(True)
self.__label.setText("Finished")
self.__runner = Runner()
class Runner(QRunnable):
def __init__(self):
QRunnable.__init__(self)
self.__queue = Queue()
self.__net = Mnist(self.__queue)
self.signals = RunnerSignal()
def run(self):
self.__net.start()
while True:
data = self.__queue.get()
if data == NetSignal.finished:
self.signals.finished.emit()
break
def close(self):
self.__net.end_process()
class RunnerSignal(QObject):
finished = pyqtSignal()
class Mnist(Process):
def __init__(self, queue: Queue):
Process.__init__(self)
self.__queue = queue
def run(self):
mnist = tf.keras.datasets.mnist # 28x28 Bilder hangeschriebener Ziffern von 0-9
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = tf.keras.utils.normalize(x_train, axis=1)
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(128, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(128, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(10, activation=tf.nn.softmax))
model.compile(optimizer="adam",
loss="sparse_categorical_crossentropy",
metrics=['accuracy'])
model.fit(x_train, y_train, epochs=8)
self.__queue.put(NetSignal.finished)
self.__queue.close()
def end_process(self):
self.terminate()
self.__queue.put(NetSignal.finished)
self.__queue.close()
class NetSignal:
finished = "finished"
if __name__ == "__main__":
main_thread = QApplication(argv)
main_window = Window()
main_window.show()
exit(main_thread.exec())
添加回答
舉報(bào)