【无标题】

如果子进程的任务耗时较长,并且在退出时仍在执行,那么在退出事件处理函数中等待子进程结束可能会导致界面卡顿。为了解决这个问题,可以使用一种异步的方式来处理子进程的终止。

一种常见的方法是使用信号量(Semaphore)来控制子进程的终止。通过引入一个信号量,我们可以在退出事件处理函数中发送一个信号给子进程,告知它应该尽快终止任务。子进程可以在适当的时候检查这个信号,并在接收到信号后尽快终止任务。

以下是修改后的代码示例:

 其中退出进程线程的部分需要修改一下。

from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QMessageBox
from multiprocessing import Process, Queue
import threading
import time
import sys
from multiprocessing import Semaphore

class MyProcess(Process):
    def __init__(self, q, data, semaphore):
        super().__init__()
        self.q = q
        self.data = data
        self.semaphore = semaphore

    def run(self):
        time.sleep(20)
        # 检查信号量,如果接收到信号则终止任务
        if self.semaphore.acquire(blocking=False):
            print('接收到终止信号,子进程终止任务')
            return

        print('子进程开始put数据')
        self.data.append('123')
        self.q.put(self.data)

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.q = Queue()
        self.data = ['111', '222', '333']  # 要传递的列表
        self.semaphore = Semaphore(0)  # 初始化信号量

        self.button = QPushButton('启动子进程', self)
        self.button.clicked.connect(self.start_child_process)

    def start_child_process(self):
        def run_child_process():
            p = MyProcess(self.q, self.data, self.semaphore)
            p.start()
            p.join()

            # 子进程完成后的逻辑
            result = self.q.get()
            print('主进程获取Queue数据:', result)

        self.thread = threading.Thread(target=run_child_process)
        self.thread.start()

    def closeEvent(self, event):
        reply = QMessageBox.question(self, '退出确认', '确定要退出吗?',
                                     QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            # 发送终止信号给子进程
            self.semaphore.release()
            event.accept()
        else:
            event.ignore()

if __name__ == '__main__':
    app = QApplication([])
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

我们引入了一个Semaphore对象semaphore,用于控制子进程的终止。在子进程的run方法中,首先检查信号量是否被获取(即是否接收到终止信号),如果是,则终止任务并返回。这样可以确保子进程在接收到终止信号后尽快终止任务。

在退出事件处理函数closeEvent中,我们调用self.semaphore.release()发送终止信号给子进程。然后,我们接受退出事件(调用event.accept()),这样应用程序会终止。

通过这样的处理,当用户点击关闭按钮时,会发送终止信号给子进程,子进程在适当的时候终止任务,从而避免了界面卡顿的问题。

你可能感兴趣的:(PyQT)