在PyQt5中进行多线程编程时,安全地暂停和恢复线程是一个常见的需求。与强制终止和重启线程相比,暂停和恢复线程可以避免资源浪费和潜在的数据不一致问题。以下是实现线程安全暂停和恢复的步骤:
QThread
和 QMutex
QThread
是 PyQt5 中用于多线程编程的核心类,而 QMutex
用于线程间的同步。我们可以通过 QMutex
来实现线程的暂停和恢复。
我们可以在自定义的线程类中添加一个标志位和一个 QMutex
对象来控制线程的执行。
from PyQt5.QtCore import QThread, QMutex, QWaitCondition, pyqtSignal
class WorkerThread(QThread):
def __init__(self):
super().__init__()
self.mutex = QMutex()
self.condition = QWaitCondition()
self.paused = False
self.stopped = False
def run(self):
while not self.stopped:
self.mutex.lock()
if self.paused:
self.condition.wait(self.mutex)
self.mutex.unlock()
# 这里是线程的主要工作逻辑
print("Working...")
self.msleep(500) # 模拟工作
def pause(self):
self.mutex.lock()
self.paused = True
self.mutex.unlock()
def resume(self):
self.mutex.lock()
self.paused = False
self.condition.wakeAll()
self.mutex.unlock()
def stop(self):
self.mutex.lock()
self.stopped = True
self.condition.wakeAll()
self.mutex.unlock()
self.wait()
在主线程中,你可以通过调用 pause()
和 resume()
方法来控制工作线程的暂停和恢复。
from PyQt5.QtWidgets import QApplication, QPushButton, QVBoxLayout, QWidget
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.worker = WorkerThread()
self.worker.start()
self.pause_button = QPushButton("Pause")
self.resume_button = QPushButton("Resume")
self.stop_button = QPushButton("Stop")
self.pause_button.clicked.connect(self.worker.pause)
self.resume_button.clicked.connect(self.worker.resume)
self.stop_button.clicked.connect(self.worker.stop)
layout = QVBoxLayout()
layout.addWidget(self.pause_button)
layout.addWidget(self.resume_button)
layout.addWidget(self.stop_button)
self.setLayout(layout)
if __name__ == "__main__":
app = QApplication([])
window = MainWindow()
window.show()
app.exec_()
WorkerThread
类:这是一个自定义的线程类,继承自 QThread
。它包含了一个 QMutex
和一个 QWaitCondition
对象,用于控制线程的暂停和恢复。pause()
方法:将 paused
标志位设置为 True
,并调用 condition.wait()
使线程进入等待状态。resume()
方法:将 paused
标志位设置为 False
,并调用 condition.wakeAll()
唤醒等待的线程。stop()
方法:将 stopped
标志位设置为 True
,并唤醒线程以便它可以正常退出。QMutex
进行保护,以避免竞态条件。通过这种方式,你可以安全地暂停和恢复线程,而不需要强制终止和重启线程。