博客
关于我
【从零学习python 】85.Python进程池的并行计算技术应用
阅读量:589 次
发布时间:2019-03-11

本文共 2431 字,大约阅读时间需要 8 分钟。

进程池是Python中一个强大的工具,用于高效管理多进程任务。对于需要同时执行大量任务但又不希望手动创建大量进程的情况,Python的multiprocessing模块提供了Pool功能,能够自动管理进程的数量和生命周期。

初始化与使用

使用Pool时,首先需要指定最大进程数。Pool会根据需求自动创建新的进程来处理任务。当任务数量超过最大进程数时,会采用等待策略,等待现有的进程完成后再创建新的进程。例如,以下代码创建一个最多运行3个进程的池:

from multiprocessing import Pool
import os, time, random
def worker(msg):
t_start = time.time()
print(f"{msg}开始执行,进程号为{os.getpid()}")
time.sleep(random.random() * 2)
t_stop = time.time()
print(f"{msg}执行完毕,耗时{t_stop - t_start:.2f}")
po = Pool(3)
for i in range(10):
po.apply_async(worker, (i,))

运行效果

运行上述代码时,池会自动分配任务给多个进程。每个进程会独立执行任务,并根据随机时间延迟后完成。这样可以显著提高任务处理效率。

常用函数解析

Pool提供了多个功能性方法,主要包括:

  • apply_async(func, [args], [kwds]):非阻塞地提交任务给池执行。
  • close():关闭池,停止接受新任务。
  • terminate():立即终止所有进程,不管任务是否完成。
  • join():阻塞主进程,等待所有子进程完成。
  • 进程池中的Queue通信

    在进程池中,进程间的通信通常需要通过Queue实现。需要注意的是,multiprocessing模块的Queue必须通过Manager创建,而不是直接使用multiprocessing.Queue,否则会出现以下错误:

    RuntimeError: Queue objects should only be shared between processes through inheritance.

    以下示例展示了进程池中进程如何通过队列实现通信:

    from multiprocessing import Manager, Pool
    import os, time, random
    def reader(q):
    print(f"reader启动({os.getpid()}),父进程为({os.getppid()})")
    for i in range(q.qsize()):
    print(f"reader从Queue获取到消息:{q.get(True)}")
    def writer(q):
    print(f"writer启动({os.getpid()}),父进程为({os.getppid()})")
    for i in "helloworld":
    q.put(i)
    if __name__ == "__main__":
    print(f"({os.getpid()}) start")
    q = Manager().Queue()
    po = Pool()
    po.apply_async(writer, (q,))
    time.sleep(1)
    po.apply_async(reader, (q,))
    po.close()
    po.join()
    print(f"({os.getpid()}) End")

    进阶案例

    以下是一个更复杂的案例,展示了如何在多个进程之间通过队列进行通信和数据传递:

    from multiprocessing import Manager, Pool
    import os, time, random
    def reader(q):
    print(f"reader启动({os.getpid()}),父进程为({os.getppid()})")
    while True:
    if not q.empty():
    print(f"reader从Queue获取到消息:{q.get(True)}")
    time.sleep(0.1)
    def writer(q):
    print(f"writer启动({os.getpid()}),父进程为({os.getppid()})")
    for i in range(5):
    msg = f"消息{i}"
    print(f"writer将消息'{msg}'添加到Queue")
    q.put(msg)
    time.sleep(0.2)
    if __name__ == "__main__":
    print(f"({os.getpid()}) start")
    q = Manager().Queue()
    po = Pool()
    po.apply_async(writer, (q,))
    time.sleep(0.5)
    po.apply_async(reader, (q,))
    po.close()
    po.join()
    print(f"({os.getpid()}) End")

    通过以上案例可以看到,进程池和队列是实现多进程任务并行执行和通信的强大工具。在实际应用中,可以根据需求灵活配置池的大小和任务的执行策略,以达到最佳性能。

    转载地址:http://gsavz.baihongyu.com/

    你可能感兴趣的文章
    mysql 8 远程方位_mysql 8 远程连接注意事项
    查看>>
    MUI框架里的ajax的三种方法
    查看>>
    MySQL 8.0 恢复孤立文件每表ibd文件
    查看>>
    Mysql 8.0 新特性
    查看>>
    MultCloud – 支持数据互传的网盘管理
    查看>>
    MySQL 8.0.23中复制架构从节点自动故障转移
    查看>>
    MySQL 8.0开始Group by不再排序
    查看>>
    mysql ansi nulls_SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON 什么意思
    查看>>
    multi swiper bug solution
    查看>>
    MySQL Binlog 日志监听与 Spring 集成实战
    查看>>
    MySQL binlog三种模式
    查看>>
    multi-angle cosine and sines
    查看>>
    Mysql Can't connect to MySQL server
    查看>>
    mysql case when 乱码_Mysql CASE WHEN 用法
    查看>>
    Multicast1
    查看>>
    mysql client library_MySQL数据库之zabbix3.x安装出现“configure: error: Not found mysqlclient library”的解决办法...
    查看>>
    MySQL Cluster 7.0.36 发布
    查看>>
    Multimodal Unsupervised Image-to-Image Translation多通道无监督图像翻译
    查看>>
    MySQL Cluster与MGR集群实战
    查看>>
    multipart/form-data与application/octet-stream的区别、application/x-www-form-urlencoded
    查看>>