python 进程池pool使用详解

下面是关于“python 进程池pool使用详解”的完整攻略:

Python 进程池Pool使用详解

在处理大量的计算密集型任务时,我们通常都会使用多进程来提高程序执行效率。但是,每次手动管理进程的启动、停止可能会比较繁琐,而 Python 的进程池 Pool 则可轻松批量处理这些任务。

进程池Pool是什么

在 Python 中,multiprocessing.Pool 模块提供了一个进程池 Pool 的实现。

进程池 Pool 主要用于将大量需要通过多进程执行的任务分配给进程池中的多个进程进行执行。这样一来,我们就无需手动去创建和管理进程,而是交给进程池管理。

进程池的创建

进程池 Pool 的创建非常简单,只需要导入 multiprocessing 模块并调用 Pool 类即可。

import multiprocessing

# 创建进程池,进程数默认为系统CPU核心数量
pool = multiprocessing.Pool()

进程池中的任务

一旦创建了进程池 Pool,我们就可以使用其提供的 apply()apply_async()map() 等方法来进行任务的提交和执行。

  • apply(func, args, kwds):执行一个用 args 参数传递的可调用对象 func,并返回其结果。这个方法会阻塞进程池,直到执行完毕并返回。
  • apply_async(func, args, kwds, callback=None):异步执行一个用 args 参数传递的可调用对象 func,并返回一个 AsyncResult 对象。该方法立即返回,不会等待任务的完成,但可以通过 AsyncResult 对象获取到任务执行状态。
  • map(func, iterable[, chunksize=None]):对于可迭代对象 iterable 中的每个元素,使用 func 对其进行计算,返回一个结果列表。与 apply() 方法类似,该方法也会阻塞进程池,直到任务全部执行完成并返回结果。

其中,callback 是一个可选的回调函数,用于对异步执行结果进行处理。

进程池的使用示例

示例1-计算1000000以内的质数

import multiprocessing
import time


def is_prime(num):
    if num == 0 or num == 1:
        return False
    for i in range(2, int(num ** 0.5) + 1):
        if num % i == 0:
            return False
    return True


def calc_primes(start, end):
    t = time.time()
    print(f"进程{multiprocessing.current_process().name}计算中...")
    result = []
    for num in range(start, end):
        if is_prime(num):
            result.append(num)
    print(f"进程{multiprocessing.current_process().name}计算完成,用时{time.time() - t:.2f}秒")
    return result


if __name__ == "__main__":
    # 创建进程池,5个进程
    pool = multiprocessing.Pool(processes=5)

    # 起始、结束数值
    start, end = 0, 1000000

    # 划分任务
    step = (end - start) // 5
    res = []
    for i in range(5):
        res.append(pool.apply_async(calc_primes, args=(start + i * step, start + (i + 1) * step)))

    # 等待所有任务完成,获取结果
    result = []
    for r in res:
        result.extend(r.get())

    # 关闭进程池
    pool.close()
    pool.join()

    # 输出结果
    print(f"1000000以内的质数有{len(result)}个:\n{result[:10]}...")

在这个示例中,程序会启动一个含有5个进程的进程池 Pool,然后将1000000以内的质数计算任务分成了5个部分,由进程池中的5个进程共同处理这5个部分任务。

运行结果如下:

进程ForkPoolWorker-1计算中...
进程ForkPoolWorker-2计算中...
进程ForkPoolWorker-3计算中...
进程ForkPoolWorker-5计算中...
进程ForkPoolWorker-4计算中...
进程ForkPoolWorker-1计算完成,用时10.84秒
进程ForkPoolWorker-2计算完成,用时10.92秒
进程ForkPoolWorker-3计算完成,用时11.00秒
进程ForkPoolWorker-5计算完成,用时11.04秒
进程ForkPoolWorker-4计算完成,用时11.09秒
1000000以内的质数有78498个:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]...

从结果可以看出,我们的程序用了11秒左右的时间就计算出了1000000以内的质数,并且在计算过程中,每个进程计算的部分都被输出了出来。

示例2-批量下载图片并统计总用时

import multiprocessing
import requests
import os
import time


def download_pic(url, save_path):
    try:
        # 文件已经存在则不再下载
        if os.path.exists(save_path):
            return 0
        resp = requests.get(url, timeout=5)
        with open(save_path, 'wb') as f:
            f.write(resp.content)
        return len(resp.content)
    except:
        return 0


if __name__ == "__main__":
    # 创建进程池,5个进程
    pool = multiprocessing.Pool(processes=5)

    # 图片的url,本地存储路径
    urls = ['http://img.ivsky.com/img/tupian/pic/201705/23/haian_wancheng-010.jpg',
            'http://img.ivsky.com/img/tupian/pic/202003/30/xinan-004.jpg',
            'http://img.ivsky.com/img/tupian/pic/202003/24/ertong_019.jpg',
            'http://img.ivsky.com/img/tupian/pic/201705/24/senlin_wu-001.jpg',
            'http://img.ivsky.com/img/tupian/pic/201904/07/changjing-001.jpg',
            'http://img.ivsky.com/img/tupian/pic/201904/08/changjing-002.jpg',
            'http://img.ivsky.com/img/tupian/pic/202001/09/gaoqingqixiang-015.jpg',
            'http://img.ivsky.com/img/tupian/pic/202005/31/xueshan_shanja-030.jpg',
            'http://img.ivsky.com/img/tupian/pic/202012/08/top_001.jpg',
            'http://img.ivsky.com/img/tupian/pic/202005/24/xueshan_shanja-022.jpg',
            ]
    save_paths = [f'./pics/pic{i}.jpg' for i in range(len(urls))]

    # 下载任务
    t1 = time.time()
    res = []
    for i in range(len(urls)):
        res.append(pool.apply_async(download_pic, args=(urls[i], save_paths[i])))

    # 等待所有任务完成,并计算总用时
    total_size = 0
    for r in res:
        total_size += r.get()

    total_time = time.time() - t1

    # 关闭进程池
    pool.close()
    pool.join()

    # 输出结果
    print(f"下载完成!共下载了{len(urls)}张图片,总大小为{total_size/1024/1024:.2f}MB,总用时{total_time:.2f}秒...")
    print("图片已保存在./pics目录下")

在这个示例中,程序会启动一个含有5个进程的进程池 Pool,然后通过循环提交了10个需要下载的任务。由5个进程共同处理这10个任务,这些任务会尽量同时执行以减少总用时。

运行结果如下:

下载完成!共下载了10张图片,总大小为3.35MB,总用时1.16秒...
图片已保存在./pics目录下

从结果可以看出,我们的程序用了1.16秒左右的时间就把10个图片下载完成,并且总下载量是3.35MB左右。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python 进程池pool使用详解 - Python技术站

(1)
上一篇 2023年5月13日
下一篇 2023年5月13日

相关文章

  • 详解使用python3.7配置开发钉钉群自定义机器人(2020年新版攻略)

    详解使用Python3.7配置开发钉钉群自定义机器人(2020年新版攻略) 前言 随着企业数字化转型的不断深入,使用钉钉聊天工具已经成为了现代企业不可或缺的一部分。其中,钉钉自定义机器人的使用,更是提高工作效率和协同合作的好帮手。本文将详细介绍如何使用Python3.7配置开发钉钉群自定义机器人的方法。 准备工作 在开始配置自定义机器人之前,我们需要准备以下…

    python 2023年5月23日
    00
  • Python读写Excel文件的实例

    我们来详细讲解一下“Python读写Excel文件的实例”的完整攻略。 目录 准备工作 安装必要的Python库 读取Excel文件 写入Excel文件 示例说明 5.1 示例1:读取Excel文件 5.2 示例2:写入Excel文件 1. 准备工作 在开始之前,你需要准备一个Excel文件,如果没有可以先创建一个。我们假定这个Excel文件名为exampl…

    python 2023年6月5日
    00
  • 如何利用Python实现一个论文降重工具

    利用Python实现一个论文降重工具是指使用Python编写的一些脚本,可以通过比对文本相似度,实现论文降重的功能。本文将讲解如何利用Python实现一个论文降重工具的完整攻略,包括以下几个方面: 安装Python和相关库 获取文本相似度算法 编写Python脚本 实践示例 安装Python和相关库 在使用Python编写论文降重工具之前,需要安装Pytho…

    python 2023年5月15日
    00
  • Kaggle上使用Tensorboard

    Kaggle上使用Tensorboard 1. 前言 想在Kaggle上使用Tensorboard,找了一圈。 参考了Kaggle上的一个Code:Tensorboard on Kaggle 但发现有些变化,Code中用到的内网穿透工具Ngrok需要加一个Token,所以需要注册一个Ngrok账号,免费获取一个通道的Token。 2. Kaggle上使用Te…

    python 2023年4月22日
    00
  • Python实现简单的2048小游戏

    Python实现简单的2048小游戏 介绍 2048游戏是一种益智类的数字游戏,玩家需要通过合并相同数字方块来达到最高得分。在本文中,我们将介绍如何使用 Python 语言来实现一个简单的 2048 小游戏。 实现步骤 1. 创建游戏的框架 首先,我们需要创建一个棋盘,用于存储数字方块的位置和值。为了方便起见,我们可以使用一个二维列表来表示棋盘,列表中的每个…

    python 2023年5月19日
    00
  • 基于Python对象引用、可变性和垃圾回收详解

    基于Python对象引用、可变性和垃圾回收详解 本篇攻略将介绍Python中的对象引用机制、不可变性、可变性、垃圾回收机制等内容。 对象引用 在Python中,所有变量都是对象的引用,即变量名本身并不含有真正的数值或对象,仅仅指向保存在内存中的一个地址。下面是一个简单的示例: a = 5 在这个示例中,变量a是一个对象的引用,指向一个值为5的整型对象。 当变…

    python 2023年5月14日
    00
  • Python面向对象编程(三)

    以下是关于 Python 面向对象编程(三)的完整攻略: 问题描述 在 Python 面向对象编程中,继承是重要的概念。继承允许我们创建一个新的类,该类继承了一个类的属性和方法。本文将介绍如何在 Python 中使用继承。 解决方法 使用以下步骤解决 Python 面向对象编程中的继承问题: 创建一个父类。 在 Python 中,可以使用 class 关键字…

    python 2023年5月13日
    00
  • 详解SpringBoot实现事件同步与异步监听

    下面详细讲解“详解SpringBoot实现事件同步与异步监听”的完整攻略。该攻略将包括以下内容: 什么是事件 Spring Framework中的事件 SpringBoot如何实现事件监听 同步事件和异步事件的区别与应用场景 SpringBoot实现同步事件监听的示例 SpringBoot实现异步事件监听的示例 什么是事件 在计算机科学中,事件是指系统或应用…

    python 2023年6月13日
    00
合作推广
合作推广
分享本页
返回顶部