先说说项目的背景
自己用pyqt做了一个界面,大家都知道qt的主线程不能阻塞,一旦阻塞的话在不同的界面就会出现卡顿的问题
我在一个tab当中有一个需要消耗很长时间的funcA,我之前的办法是将funcA放到子线程。
但是后面需要funcA的返回数据,那么我想到了之前说的两种方法,一个是重写线程类,一个是queue让子线程和父线程进行通信。
但是实际的使用会发现,都会出现父线程等待子线程结束之后拿到数据的问题。不然的话,你接受queue的数据的时候就会是None!
这里再说一下提的问题
本质是一个子线程当中的函数funcA需要花费很久时间才能有结果。如何在不堵塞父线程的情况下从子线程当中获得返回子线程的结果
如下代码,我现在需要获得funcA和funcB两个函数的返回值
def funcA():
#spend much time
return resa
def funcB():
#spend much time
return res
如果我不使用线程的话那么执行funcA或者funcB都是只能执行一个,另外一个只有等
funcA()
funcB() #只有等待funA执行完之后才能执行funB ,堵塞
后面我使用了多线程进行处理
qa = queue.Queue(10)
def funcA():
# 花费很多时间做一些事得到一个数组叫做 res
for i in res:
qa.put(i)
def funcB():
# 花费很多时间做一些事得到一个数组叫做 res
for i in res:
qb.put(i)
resa=[]
threadA = Thread(target=funcA, args=(xx))
threadA.start()
threadB = Thread(target=funcB, args=(xx))
threadB.start()
while not empty(qa.get()): #实际执行的时候你会发现如果没有写join的话,这里的res会得到None,因为线程A并没有执行完成,但是如果写了join的话,那么实际上还是和之前没有使用多线程一样,做了funcA等待funcA执行完成之后才能做funcB
res.append(qa.get())
qb = queue.Queue(10)
resb=[]
while not empty(qb.get()):
res.append(qb.get())
写出上面这段代码就是我提出问题的节点。我发现如果想要得到其中线程的返回数据的时候还是会出现堵塞的情况?有没有什么写法能够得让funcA和funcB都能得到结果并且不会相互之间不会被堵塞呢?
各位大哥提出的几种方法
1.使用线程池
这个方法在等待后面子线程数据返回的时候主线程是堵塞的,因为要调用get_result,就会一直堵塞。
但是这个方法给了我灵感十分感谢!
2.放弃多线程使用异步
仔细想了想,也是可以使用的,我们堵塞的本质是因为一直要监听子进程的返回,那么如果使用异步是可以的!
是否表明异步和多线程底层实现具有相关性呢
最后的解决方法
新建一个funC,在funC当中创建线程池funcA和funcB的线程,并在其中等待funcA和funcB的返回结果并且进行处理
然后在主线程当中创建funC的线程,这样不管funcA和funcB如何堵塞都不会让主线程堵塞了!