深入解析Python multiprocessing.Pool.map()的执行机制与顺序
本文通过四个具体示例,深入解析Python中multiprocessing模块Pool.map()方法的执行实质。重点探讨进程池大小、任务耗时对总执行时间的影响,以及输入列表顺序与输出结果的一一对应关系。通过对比不同场景下的运行日志,阐明Pool.map按序分发任务且保持结果顺序的核心特性,帮助开发者优化多进程编程策略。
在多进程编程中,我通常采用multiprocessing模块提供的Pool.map()方法来实现并行处理。下文将通过一个基础示例及其详细解析来展开讨论。关于该方法在多进程场景下的具体效率表现,欢迎技术专家指正与探讨。
示例代码展示:
"""
探索pool.map多进程执行方式的实质
"""
from multiprocessing import Pool
from time import sleep
from datetime import datetime
class forMap:
def __init__(self):
self.name = '没啥用的初始化'
def forPrinit(self, i):
sleep(i)
print(i)
return i ** 2
基础代码框架已构建完毕,接下来我们将观察多进程的实际执行过程。
示例1的执行配置:
if __name__ == '__main__':
s = datetime.now()
tt = forMap()
# 进程池中创建两个进程,调用计算机的两个内核去帮我做事。
p = Pool(2)
l = [2, 4, 6]
rList = p.map(tt.forTest, l)
print(rList)
p.close()
p.join()
e = datetime.now()
print('多进程执行时间:', e - s)
运行输出结果如下:
2 4 6 [4, 16, 36] 多进程执行耗时:0:00:08.191251
在此示例中,进程池配置了两个进程,因此代码会占用计算机的两个CPU内核。列表l包含三个元素,前两个元素“2”和“4”会依次被分发到内核A和内核B执行。当某个内核执行完毕后,会立即接收下一个参数“6”。由于内核A处理的任务耗时较短(仅sleep 2秒),它会在完成第一个任务后迅速接手参数“6”的处理。因此,内核A总共执行了耗时2秒和6秒的任务,累计8秒。由于是并行执行,整体耗时由最长路径决定,即8秒左右(多出的零点几秒用于进程初始化、数据赋值及打印输出等开销)。
示例2的执行配置:
if __name__ == '__main__':
s = datetime.now()
tt = forMap()
# 进程池中创建三个进程
p = Pool(3)
l = [2, 4, 6]
rList = p.map(tt.forTest, l)
print(rList)
p.close()
p.join()
e = datetime.now()
print('多进程执行时间:', e - s)
运行输出结果如下:
2 4 6 [4, 16, 36] 多进程执行耗时:0:00:06.273263
此示例创建了三个进程进行并行执行,因此总执行时间约为6秒(由最长任务决定)。
示例3的执行配置:
if __name__ == '__main__':
s = datetime.now()
tt = forMap()
# 进程池中创建三个进程
p = Pool(3)
l = [2, 4, 6, 8]
rList = p.map(tt.forTest, l)
print(rList)
p.close()
p.join()
e = datetime.now()
print('多进程执行时间:', e - s)
运行输出结果如下:
2 4 6 8 [4, 16, 36, 64] 多进程执行耗时:0:00:10.211451
在列表中添加元素“8”后,进程A、B、C分别先处理“2”、“4”和“6”。由于内核A处理的任务最快结束,它会立即接手新加入的元素“8”进行处理。
示例4的执行配置:
if __name__ == '__main__':
s = datetime.now()
tt = forMap()
# 进程池中创建三个进程
p = Pool(2)
l = [2, 4, 8, 6]
rList = p.map(tt.forTest, l)
print(rList)
p.close()
p.join()
e = datetime.now()
print('多进程执行时间:', e - s)
运行输出结果如下:
2 4 8 6 [4, 16, 64, 36] 多进程执行耗时:0:00:10.200389
保持两个进程的配置,但将列表中第3和第4个元素的位置互换(即输入顺序变为2, 4, 8, 6)。执行结果耗时10秒多,且返回值列表中的元素顺序与输入列表严格对应(即第3个元素对应8的平方,第4个元素对应6的平方)。这充分说明Pool.map方法中,可迭代对象是按顺序逐个提取元素分发给进程,且返回结果列表的顺序与输入列表的顺序保持一致。
以上即为本文的全部内容,希望这些解析能对您的学习有所帮助,也欢迎大家继续支持本站。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









