【发布时间】:2014-09-26 07:34:05
【问题描述】:
请解释我们如何从队列管理的线程发送/接收数据......
首先,我定义了它的 run() 方法的子类 'QThread',该方法在调用 QThread's.start() 时启动:
class SimpleThread(QtCore.QThread):
def __init__(self, queue, parent=None):
QtCore.QThread.__init__(self, parent)
self.queue=queue
def run(self):
while True:
arg=self.queue.get()
self.fun(arg)
self.queue.task_done()
def fun(self, arg):
for i in range (3):
print 'fun: %s'%i
self.sleep(1)
return arg+1
然后我声明两个 Thread 实例(因此只占用两个 CPU 内核)发送 self.queue 实例作为参数。
self.queue=queue.Queue()
for i in range(2):
thread=SimpleThread(self.queue)
thread.start()
现在,如果我理解正确,thread.start() 不会开始任何事情。真正的“开始”只有在我调用queue.put()时才会发生:
for arg in [1,2,3]: self.queue.put(arg)
最后一行是“真正的”调用。除了创建和启动 Queue item,put() 还允许将任意值保存到每个 Queue item。 .put() 一次做几件事:它创建,它开始,它通过队列移动处理,它允许将一个变量放在队列项目的“内部”(稍后可以从函数处理器内部检索到:使用队列项的 '.get()` 方法)。
但是我如何从fun() 函数返回值。 “常规”fun() 的return resultValue 不起作用。而且我不能使用 self.queue.put() 方法,因为这种方法除了存储数据“创建”一个新的队列项......
稍后编辑:
这里是稍微调整的代码(从另一篇文章复制/粘贴),展示了如何从已完成的线程返回值的方法。我不确定这里使用的方法是否适用于 QThread...如果我错了,请纠正我:
import os, sys
import threading
import Queue
def callMe(incomingFun, daemon=False):
def execute(_queue, *args, **kwargs):
result=incomingFun(*args, **kwargs)
_queue.put(result)
def wrap(*args, **kwargs):
_queue=Queue.Queue()
_thread=threading.Thread(target=execute, args=(_queue,)+args, kwargs=kwargs)
_thread.daemon=daemon
_thread.start()
_thread.result_queue=_queue
return _thread
return wrap
@callMe
def localFunc(x):
import time
x = x + 5
time.sleep(5)
return x
thread=localFunc(10)
# this blocks, waiting for the result
result = thread.result_queue.get()
print result
【问题讨论】:
-
你几乎不应该从 QThread 派生。您可以使用信号和槽将消息从工作线程传递到主线程。但是Qt Concurrent 更方便您的任务。
-
@PavelStrakhov 我不认为
QtConcurrent在任何 Qt 的 Python 绑定中都可用。 -
首先让我们澄清一下我们如何处理来自
fun()函数的返回值。然后我们可以讨论应该导出什么和不应该导出什么。 -
您希望
SimpleThread在后台永远运行,还是应该在您向其传递任意数量的值后结束? -
一般情况下,您会为结果创建第二个返回队列。
标签: python multithreading qt pyqt