进程池中父子进程通信

项目中碰到了这样的一个问题,我的意图是实现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了。


晓得了这个思路之后,剩下的就是将其带入项目中进行实现。最终我实现了进度条实时根据项目进度更新的目的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容