python 进程池pool使用详解

yizhihongxing

下面是关于“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日

相关文章

  • 用python进行视频剪辑

    用 Python 进行视频剪辑的完整攻略 介绍 很多人在创作视频时都需要进行剪辑,例如删减无用镜头、调整视频长度等等。这些任务通常需要使用视频编辑软件,例如Adobe Premiere和Final Cut Pro等。然而,如果你想批量剪辑大量视频,或者想用编程方式剪辑视频,Python将为你提供方便的解决方案。 在本文中,我们将介绍如何使用Python进行视…

    python 2023年6月2日
    00
  • python实现井字棋游戏

    Python实现井字棋游戏攻略 介绍 井字棋是一种简单而有趣的棋类游戏。两个玩家交替在3×3的网格上画出X和O。当其中一位玩家在水平、垂直或对角线方向上连成了三个相同符号时,他就获胜了。如果所有的网格都填满了但未有人获胜,则为平局。 在此,我们将通过使用Python来实现井字棋游戏。 游戏设计 为实现井字棋游戏,我们需要完成以下步骤: 首先,我们要创建一个3…

    python 2023年6月3日
    00
  • python分析apache访问日志脚本分享

    下面是“Python分析Apache访问日志脚本分享”的完整攻略,内容包括:准备工作、脚本编写、示例说明等。 准备工作 在编写Python访问日志分析脚本之前,需要完成以下一些准备工作: 安装Python3 安装用于解析访问日志的Python模块(如pyapachelog) 脚本编写 第一步:导入模块和定义变量 首先,需要在Python脚本中导入pyapac…

    python 2023年5月23日
    00
  • Python推导式使用详情

    对于“Python推导式使用详情”的完整攻略,我会分以下几个方面来讲解: 什么是Python推导式 Python推导式的种类 Python推导式的使用方法 Python推导式的示例 1. 什么是Python推导式 Python推导式是用来简化某些特殊类型的代码的一种语法结构。其基本思想是通过一种简洁的方式提取一种数据集合中的有用数据,而且通常还能够对这些数据…

    python 2023年5月14日
    00
  • 使用python将mysql数据库的数据转换为json数据的方法

    将MySQL数据库的数据转换为JSON数据可以通过Python标准库中的json模块进行实现。 步骤一:连接MySQL 使用Python的mysql.connector模块来连接MySQL数据库,确保已安装该模块。以下是连接MySQL数据库的示例代码: import mysql.connector db = mysql.connector.connect( …

    python 2023年5月13日
    00
  • Python 使用有限迭代器

    Python中的有限迭代器 (finite iterator) 指的是一次性的迭代器,即使用后就不能再次迭代。一些Python内置的函数(如sorted和max)以及一些外部库(如pandas和numpy)也提供了一些有限迭代器。 Python有限迭代器主要有以下几种类型: zip(): 这个函数可以接受任意多个可迭代对象,将它们中对应的元素打包成一个元组(…

    python-answer 2023年3月25日
    00
  • 使用Python爬虫爬取小红书完完整整的全过程

    下面是使用Python爬虫爬取小红书的完整攻略: 步骤一:分析目标网站 在开始爬取之前,我们需要先了解目标网站的结构和数据。对于小红书,它是一个社交电商平台,主要的数据都是用户发布的笔记、评论和赞。我们可以先打开小红书网站,浏览一些笔记和评论,观察它们的网页结构,并使用浏览器开发者工具(F12)来查看网页源代码。 步骤二:选择合适的爬虫框架 目前比较流行的P…

    python 2023年6月3日
    00
  • Python自动发送和收取邮件的方法

    以下是Python自动发送和收取邮件的方法的完整攻略。 准备工作 在进行Python自动发送和收取邮件之前,你需要进行以下几个准备工作: 邮箱账号和密码:你需要有自己的邮箱账号和对应的密码。 SMTP服务器地址和端口号:SMTP(Simple Mail Transfer Protocol)服务器是发送邮件的服务器,不同的邮箱服务商有不同的SMTP服务器地址和…

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