python - 如何在 Process() 中中断 Queue.get()?
问题描述
在目标函数中实现队列时,我无法停止进程run_event()
。队列需要从目标函数返回一个值。该过程可以在没有队列的情况下停止。
from PyQt5.QtWidgets import QHBoxLayout, QApplication, QWidget, QPushButton
from PyQt5.QtCore import QThread
from multiprocessing import Process, Queue,
def run_event(params, queue):
"""Run some task that cant be stopped by polling
returns a dataframe
"""
out = arbritrarySolver(params) # Runs a solver that returns a dataframe
queue.put(out)
class Worker(QObject):
def __init__(self, params):
super().__init__()
self.params = params
def stop_work(self):
self.process.terminate()
def start_work(self):
self.queue = Queue()
self.process = Process(target=run_event, args=(self.params, self.queue))
self.process.start()
output = self.queue.get() # output of run_event
class Gui(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def start_event(self):
self.worker_thread = QThread()
self.obj = worker.Worker(params)
self.obj.moveToThread(self.worker_thread)
self.worker_thread.started.connect(self.obj.start_work)
self.stopButton.clicked.connect(self.obj.stop_work)
self.worker_thread.start()
def initUI(self):
self.runButton = QPushButton('Run', self)
self.runButton.clicked.connect(self.start_event)
hbox = QHBoxLayout()
hbox.addWidget(self.runButton)
self.setLayout(hbox)
self.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = Gui()
sys.exit(app.exec_())
我如何实现run_event()
在实现队列时使用停止按钮中断的解决方案?
解决方案
问题是,当您使用 self.queue.get() 时,您正在阻塞工作人员所在的辅助线程,而不是可能的策略是使用计时器来检查队列的状态,并相应地发送信号到带有结果的 GUI。
from functools import partial
import multiprocessing as mp
from PyQt5 import QtCore, QtWidgets
from foo_package import arbritrarySolver
def run_event(params, queue):
"""Run some task that cant be stopped by polling
returns a dataframe
"""
out = arbritrarySolver(params) # Runs a solver that returns a dataframe
queue.put(out)
class Worker(QtCore.QObject):
resultChanged = QtCore.pyqtSignal(object)
finished = QtCore.pyqtSignal()
def __init__(self):
super().__init__()
self.m_timer = QtCore.QTimer(self)
self.m_timer.timeout.connect(self.check_result)
self.process = None
@QtCore.pyqtSlot()
def stop_work(self):
if isinstance(self.process, mp.Process):
self.process.terminate()
@QtCore.pyqtSlot(object)
def start_work(self, params):
self.queue = mp.Queue()
self.process = mp.Process(target=run_event, args=(params, self.queue))
self.process.start()
self.m_timer.start(0)
@QtCore.pyqtSlot()
def check_result(self):
if not self.process.is_alive():
self.finished.emit()
self.m_timer.stop()
if not self.queue.empty():
r = self.queue.get(block=False)
self.resultChanged.emit(r)
class Gui(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.worker_thread = QtCore.QThread(self)
self.worker_thread.start()
self.obj = Worker()
self.obj.moveToThread(self.worker_thread)
self.obj.resultChanged.connect(self.onResultChanged)
self.obj.finished.connect(self.onFinished)
self.initUI()
@QtCore.pyqtSlot()
def start_event(self):
params = "aaa", "bbb"
wrapper = partial(self.obj.start_work, params)
QtCore.QTimer.singleShot(0, wrapper)
self.runButton.setDisabled(True)
self.stopButton.setDisabled(False)
@QtCore.pyqtSlot()
def onFinished(self):
self.runButton.setDisabled(False)
self.stopButton.setDisabled(True)
@QtCore.pyqtSlot(object)
def onResultChanged(self, result):
print(result)
def initUI(self):
self.stopButton = QtWidgets.QPushButton("Stop")
self.stopButton.setDisabled(True)
self.runButton = QtWidgets.QPushButton("Run")
self.runButton.clicked.connect(self.start_event)
self.stopButton.clicked.connect(self.obj.stop_work)
hbox = QtWidgets.QHBoxLayout(self)
hbox.addWidget(self.runButton)
hbox.addWidget(self.stopButton)
self.show()
def closeEvent(self, event):
self.obj.stop_work()
super().closeEvent(event)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
ex = Gui()
sys.exit(app.exec_())
推荐阅读
- apache-kafka - 自定义 Spring 云应用程序 - Kafka Embeddedheader 问题
- javascript - CameraRoll.saveToCameraRoll 保存黑色图像
- blockchain - 在区块链中创建和删除文本帖子?
- c# - 使用 IBM DB2 调用 SaveChangesAsync() 时的 EF Core 2.1.1“DbUpdateConcurrencyException”
- html - Angular将表单的内容保存到json文件
- python-3.x - python有大量用作ID的问题
- javascript - 如何使用javascript从firebase中的嵌套数据库中检索所有孩子
- python - Python Selenium 右键单击
- google-app-engine - 物化缓存不起作用
- sql - 合并的决赛桌等价物是什么?