请解释如何从队列管理的线程发送/接收数据。。。。
第一个子类'QThread'定义其run()
方法,该方法在调用QThread
的.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
然后我声明两个线程实例(因此只使用两个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)
最后一行是“真正的”呼叫。除了创建和启动队列项之外,{.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
在正常情况下,您可以使用结果队列将结果发送回,然后让其他线程运行以等待结果:
主线:
这样做可以避免在等待结果时阻塞GUI的事件循环。下面是
multiprocessing.pool.ThreadPool
的等价物:这要简单得多。它在内部创建一个结果处理线程,当
fun
完成时,该线程将自动为您调用handle_result
。也就是说,您使用的是
QThread
,您希望结果更新GUI小部件,所以您真的希望将结果发送回主线程,而不是结果处理线程。在这种情况下,使用Qt的信号系统是有意义的,这样当您收到结果时,就可以安全地更新GUI:按下按钮时输出:
相关问题 更多 >
编程相关推荐