multiprocessing 的使用
pool.apply, pool.apply_async, pool.map, pool.map_async, pool.starmap
- pool.apply: 子进程会阻塞主进程
- pool.apply_async: 子进程不阻塞主进程
- pool.map: 子进程阻塞主进程
- pool.map_async: 子进程不阻塞主进程
- pool.starmap:与pool.map类似,唯一区别是解析参数的方式不同
pool.apply/apply_async与pool.map/pool.map_async的区别?
传参的方式不同
pool.apply(f, args) # 只会调用一个进程,其中args为f的参数,以元组形式传入
pool.map(f, iterable) # 传入的是多个参数组成的可迭代对象,如元组列表,可保证函数的返回结果与传入参数的顺序一致,而pool.map_async不能保证
pool.apply(f, args) # 等价于pool.apply_async(f, args).get(), apply之所以会阻塞主进程是因为get()
pool.map(f, iterable) # 可以保证结果有序,但是各个进程还是异步执行的,只是会记录各进程的调用顺序,返回结果时按顺序返回
pool.map_async(f, iterable) # 不能保证输出结果的顺序与iterable中参数的顺序一致
在做特征工程或者处理文件是经常要使用多进程,用法如下:
from multiprocessing import Pool
from functools import partial
from tqdm import tqdm # python 的一个进度条库
PROCESSES = 5 # 进程数
# pool.map
def test1(args):
age, sex = args # 没有这句话,直接print(age, sex)会报错
print(age, sex)
# pool.starmap
def test2(age, sex):
print(age, sex)
PROCESSES = 5
if __name__ == "__main__":
for f in tqdm(os.listdir(...)):
with Pool(processes=PROCESSES) as pool:
# pool.map(test1, [(12,"male")]) # 将(12, "male")当成一个整体传入,需要在函数内自己解包
# pool.starmap(test2, [(12, "male")]) # 自动解包
# pool.starmap(partial(test2, sex="male"), [(12,)]) # partial用来固定函数的一个或多个参数
pool.starmap(func, 参数元组列表) # 每个元素(元组)与不同的f关联,表示传入func的参数,参数为元组形式
from multiprocessing import Pool
def test(x):
time.sleep(1)
print(x**2)
if __name__ == "__main__":
print(os.cpu_count())
# 方式1, 2.3985689
# t1 = time.clock()
# pool = Pool(processes=7)
# for i in range(10):
# pool.apply_async(test, (i,)) # 注意使用apply_async时,不能使用with关键字
# pool.close()
# pool.join()
# t2 = time.clock()
# print((t2-t1))
# 方式2, 10.002746799999999s
# t1 = time.clock()
# for i in range(10):
# test(i)
# t2 = time.clock()
# print((t2-t1))
# 方式3, 2.3429913s
# t1 = time.clock()
# with Pool(7) as pool:
# pool.map(test, [i for i in range(10)]) # map不能使用for循环指定参数,而要以元组列表的形式传参
# t2 = time.clock()
# print((t2-t1))
# 方式4, 10.269656300000001s
t1 = time.clock()
with Pool(7) as pool:
for i in range(10):
pool.map(test, (i,)) # map不能使用for循环指定参数,而要以元组列表的形式传参
t2 = time.clock()
print((t2-t1))