python 多进程下tqdm如何显示进度条

python 多进程下tqdm如何显示进度条

问题

fastnlp dataset的apply方法增加多进程处理功能时遇见这个问题:多进程下显示所有子进程的进度条,主进程显示总进度条。

解决方法

解决思路

主要思路是采用管道通信(pipe)功能来实现子进程和主进程的交流。由于使用python的multiprocess开启进程池后主进程会阻塞,故只能在主进程中开辟一个线程来不断收集子进程的处理进度并显示;其好处是当主进程阻塞后,线程便不需要跟主进程争用处理机,其一直占用cpu资源。
这里有个小知识点是multiprocessing和multiprocess的区别,multiprocessing不能使用匿名函数作为进程池的传入参数,而multiprocess支持匿名函数。这是因为multiprocessing使用pickle作为序列化的库,但pickle不支持匿名函数;而multiprocess使用dill库作为序列化的函数,其支持匿名函数的序列化,故能使用lambda函数。fastnlp采用的是multiprocess。

总进度条和子进度条显示

python 多进程下tqdm如何显示进度条
定义_process_bar函数,收集子进程的处理进度情况并更新总进度条。
python 多进程下tqdm如何显示进度条
定义子进程的函数_apply_single,内部使用了tqdm来展示子进程的进度条;使用管道pipe与主进程交流。最新版的fastnlp默认不显示子进程的进度条。
python 多进程下tqdm如何显示进度条
上图为fastnlp dataset中的apply方法中多进程处理数据集的部分代码;首先对数据集进行切分,使用multiprocess库开辟管道,再启动线程运行_process_bar函数来显示总的进度条;然后开启进程池处理数据,其中子进程使用tqdm库自带的递归锁RLock()互斥显示进度条。最后分别将进程池和线程阻塞即可。

python 多进程下tqdm如何显示进度条
最终效果如图所示,fastnlp默认不展示子进程进度条,其显示结果只有Main这个进度条,减少打印的内容量。
具体代码可以见fastnlpv8

上一篇:Android开发(第一天)


下一篇:iOS 自动打包 IPA 相关