重新使用QRunnable

时间:2016-02-22 18:05:27

标签: multithreading qt pyqt threadpool

我一直在试验/o:n,以便启动并运行一些服务调用。我偶然发现了Qt documentation

中的以下信息
  

QThreadPool支持多次执行相同的QRunnable   从QRunnable :: run()中调用tryStart(this)。如果autoDelete是   启用QRunnable将在最后一个线程退出时被删除   运行功能。使用相同的QRunnable多次调用start()   启用autoDelete时会创建竞争条件而不是   推荐使用。

有人可以解释这意味着什么吗?我编写了以下代码,它允许我按顺序多次执行QRunnable个对象:

QRunnable

文档中的引用是否意味着我做错了?如果我将#!/usr/bin/env python from PyQt4.QtCore import QRunnable, pyqtSlot, pyqtSignal, QObject, QThread, QThreadPool from PyQt4.QtGui import QApplication, QWidget, QPushButton, QHBoxLayout, QLabel from sys import exit, argv from random import getrandbits class ServiceCallSignals(QObject): srv_status = pyqtSignal(bool) srv_running = pyqtSignal(bool) class ServiceCall(QRunnable): def __init__(self): super(ServiceCall, self).__init__() self.signals = ServiceCallSignals() def run(self): self.signals.srv_running.emit(True) call = bool(getrandbits(1)) print('QRunnable Thread ID: %d' % int(QThread.currentThreadId())) if call: QThread.sleep(5) self.signals.srv_status.emit(call) self.signals.srv_running.emit(False) class Test(QWidget): def __init__(self): super(Test, self).__init__() self.initUI() def initUI(self): layout = QHBoxLayout(self) self.cb = QPushButton('Send request', self) self.cb.clicked.connect(self.srv_send) layout.addWidget(self.cb) self.lbl = QLabel('Waiting...', self) layout.addWidget(self.lbl) self.srv = ServiceCall() self.srv.setAutoDelete(False) self.srv.signals.srv_status.connect(self.srv_receive) self.srv.signals.srv_running.connect(self.srv_block) self.tp = QThreadPool(self) self.setGeometry(300, 300, 250, 150) self.setWindowTitle('QRunnable and ROS service calls') self.show() @pyqtSlot() def srv_send(self): print('Main Thread ID: %d' % int(QThread.currentThreadId())) self.tp.start(self.srv) self.cb.setText('Running for reply') @pyqtSlot(bool) def srv_block(self, state): self.cb.setEnabled(not state) @pyqtSlot(bool) def srv_receive(self, srv_res): if srv_res: self.lbl.setText('Success') else: self.lbl.setText('Failed') self.cb.setText('Send request') def main(): app = QApplication(argv) t = Test() exit(app.exec_()) if __name__ == '__main__': main() 放在我的运行中并使用QThreadPool我会得到很多很多线程运行...

1 个答案:

答案 0 :(得分:0)

文档说支持tryStart内调用run(),而不是必需

如果您在start()之外依次调用run(),它将重新使用相同的帖子。但是,如果您在tryStart()内拨打run(),则可能会在必要时保留其他线程。