项目中碰到了这样的一个问题,我的意图是实现pyside2中的进度条实时跟进项目进度,为了防止主进程也就是程序主窗口陷入阻塞状态,我需要额外再开一个线程出来并行处理问题:
#首先需要定义一个自定义线程类
# 循环监视多进程数目
def cycleMonitorThread(self):
self.ongoing = True
qlist = []
# 使用无限循环,不间断的获取队列长度,以此更新进度条进度
while True:
# 获取队列内数据的长度,不取出,就看长度
qlist.append(self.qcount.get())
print(qlist)
so.process_update.emit(len(qlist))
# 队列的长度是绝对不会超过文件数量的,所以一旦队列长度等于了文件长度,就退出无限循环
if len(qlist) == self.progressNum:
self.ui.transformbtn.setText("转换完成")
self.ui.transformbtn.setEnabled(True)
self.ongoing = False
break
# 再在程序合适的地方插入执行线程的语句
thread1 = threading.Thread(target=self.cycleMonitorThread)
thread1.start()
我原本以为在子进程中只需要使用q = queue.Queue()
就可以在主进程和子进程中进行通信沟通。
以下插入项目的简化代码(我测试摸索问题在哪用的就是这个):
from queue import Queue
from threading import Thread
def foo(q):
q.put('hello')
return q.get()
def run(q):
p = mp.Pool()
p.apply_async(func=foo, args=(q,))
p.close()
p.join()
if __name__ == '__main__':
q = Queue()
thread = Thread(target=run, args=(q,))
thread.start()
print(q.get())
可是情况并没有我想象的那么简单,各位可以复制以上代码去运行,你们会发现q.get()
并不会返回任何数据过来
经过好几天的思考,并结合多方查询后明白了,在多进程中,queue一般适用于子进程间的通信,不能用于父子进程中的通信。那么我实在是想实现父子之间的通信该怎么办呢?
解决方法:
在父进程中使用multiprocessing.Manage()
中的Queue()
方法,然后将此对象实例化,我这里用q
表示,并将q
作为参数传进进程方法中。具体代码如下:
import multiprocessing
from threading import Thread
def foo(q):
q.put('hello')
def run(q):
p = multiprocessing.Pool()
p.apply_async(func=foo, args=(q,))
p.close()
p.join()
if __name__ == '__main__':
mg = multiprocessing.Manager()
q = mg.Queue()
thread = Thread(target=run, args=(q,))
thread.start()
print(q.get())
这次运行之后就能输出hello
了。
晓得了这个思路之后,剩下的就是将其带入项目中进行实现。最终我实现了进度条实时根据项目进度更新的目的。