类函数中获取进程池对象的地址

apply(): 首先主进程开始,碰到子进程就执行,等到子进程都执行完毕后切换到主进程,和单进程串行执行无区别

apply_async():异步非阻塞,不用等待当前进程执行完毕,随时根据系统调度进行进程切换。即便碰到主进程,子进程仍可以先运行。

import time
from multiprocessing import Pool
def run(count):
print(“子进程编号:%s” % count)
time.sleep(2)
print(“子进程%s结束” % count)
if __name__ == “__main__”:
print(“开始执行主进程”)
start_time = time.time()
# 使用进程池创建子进程
pool = Pool(4)
print(“开始执行子进程”)
for i in range(4):
pool.apply_async(run, (i, ))
print(“主进程结束,总耗时%s” % (time.time() – start_time))

现在是抢占式切换,首先运行的是主进程,主进程一下子就运行完了,子进程都没有机会切换。
若想子进程执行结束完毕后再运行主进程剩余部分,则在恰当位置加上一句”sub_process_name.join()”

import time
from multiprocessing import Pool
def run(count):
print(“子进程编号:%s” % count)
time.sleep(2)
print(“子进程%s结束” % count)
if __name__ == “__main__”:
print(“开始执行主进程”)
start_time = time.time()
# 使用进程池创建子进程
pool = Pool(4)
print(“开始执行子进程”)
for i in range(4):
pool.apply_async(run, (i, ))
pool.close() # 进程池调用close()后,会把进程池切换成不可再插入之状态
# close必须在join之前
pool.join() # join()调用后主进程必须等子进程全部运行结束后才接着运行
print(“主进程结束,总耗时%s” % (time.time() – start_time))

类函数获取进程池对象之后,就可以在用pool.apply_async(func…)在类函数里面执行,这个pool要与主进程的命名一致

pool.join()防止主进程在worker结束前结束

pool.close()等待进程池中的worker执行结束后再关闭

Test Env: Ubuntu16

一般的面向过程编程如果要采用进程池,只需要在主程序入口初始化进程池,然后可以在函数里分配任务队列。但是在面向对象编程中,如果直接采用这种方式去给类里面的函数分配任务,就会出错。这是因为:
pool方法都是用queue.Queue将task传递给工作进程,multiprocessing必须将数据序列化才能在进程间传递。即类中的方法因为被“包装”过一层,不能被序列化了。
可以采用类似全局变量的思路突破这层包装,使得类里面的方法能够感知到主程序的pool对象,例子如下:

from multiprocessing import Pool
from time import sleep
import sys
from test import Tester

if __name__ == “__main__”:
    pool = Pool(5)
    test1 = Tester()
    test1.work()
    test2 = Tester()
    test2.work()
    test3 = Tester()
    test3.work()
    test4 = Tester()
    test4.work()
    test5 = Tester()
    test5.work()
    test6 = Tester()
    test6.work()
    
    pool.close()
    pool.join()
# test.py
import sys
import os
from time import sleep class Tester: def f(self, x): for i in range(5): print(“%s---%s---%s” % (i, x, os.getpid())) sleep(1) def getPoolObject(self):
     # pool's name is defined in main()  
return sys.modules[“__mp_main__”].pool def work(self): pool = self.getPoolObject() pool.apply_async(self.f, (5, ))

输出

实际的例子:

原文地址:https://www.cnblogs.com/sayiqiu/p/10598218.html