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日

相关文章

  • python自动格式化json文件的方法

    下面是关于Python自动格式化JSON文件的方法的完整攻略。 1. 简介 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,常用于前后端数据交互、数据存储等场景。其中,使用JSON格式进行数据交换时,通常需要进行文件格式化。对于较小的JSON文件,可以使用文本编辑器进行格式化,但对于大型JSON文件,需要使用工具自…

    python 2023年6月3日
    00
  • Python中函数的创建与调用你了解吗

    当创建一个函数时,你需要使用 Python的def语句来定义函数,在函数名后面跟有圆括号,然后跟有一个冒号,再在下一行写出执行了什么样的任务的代码块。 下面是一个简单的示例函数: def greet(name): print("Hello, " + name) 这个函数在被调用时,接受一个参数,输出问候语 “Hello ” 和这个参数的值…

    python 2023年5月30日
    00
  • Python3.5内置模块之os模块、sys模块、shutil模块用法实例分析

    下面我将详细讲解一下“Python3.5内置模块之os模块、sys模块、shutil模块用法实例分析”的完整攻略。 1. os模块 1.1 os模块简介 os模块是Python的内置模块之一,主要用于与操作系统进行交互,并提供了许多处理文件和目录的方法。在大多数操作系统中,os模块提供了与操作系统底层交互的接口。 1.2 os模块常用方法介绍 1.2.1 获…

    python 2023年5月30日
    00
  • 对python中的os.getpid()和os.fork()函数详解

    对python中的os.getpid()和os.fork()函数详解 在Python中,os模块为我们提供了一些操作操作系统特定功能的接口。其中os.getpid()和os.fork()是常用的两个函数,本文将详细介绍这两个函数的使用方法和共同点以及不同点。 os.getpid() os.getpid()函数用来获取当前进程的进程ID号。其语法如下: os.…

    python 2023年5月31日
    00
  • Django 表单模型选择框如何使用分组

    使用Django表单中的选择框(select)时,有时候需要对选项进行分组,以便用户更方便地选择。本文将详细讲解如何在Django的表单中使用分组选择框。 1.创建分组选择框的选项 首先,需要创建选项和选项组。假设我们有一个产品表单,需要用户输入该产品所属的部门。在此示例中,我们创建两个有关部门的选项组:“技术部门”和“其他部门”。选项组中的每个选项都将属于…

    python 2023年6月3日
    00
  • Python批量提取PDF文件中文本的脚本

    下面是“Python批量提取PDF文件中文本的脚本”的完整攻略。 准备工作 安装依赖库 需要在Python环境下安装 pdfminer3k 库,其支持python2和python3。 可以使用 pip 命令在终端中安装: pip install pdfminer3k 下载脚本 从Github上 pdfminer-batch 下载脚本并解压,将所有 .py 文…

    python 2023年6月6日
    00
  • python opencv检测直线 cv2.HoughLinesP的实现

    针对“python opencv检测直线 cv2.HoughLinesP的实现”,以下是一份完整攻略。 一、关于cv2.HoughLinesP函数 cv2.HoughLinesP是OpenCV中检测直线的函数,通过应用霍夫变换来完成这个过程。它能够在图像中检测到一组直线,并返回一组由起点和终点组成的(x1, y1, x2, y2)值的坐标。 cv2.Houg…

    python 2023年5月18日
    00
  • python 图片验证码代码

    下面是“python图片验证码代码”的完整攻略: 1. 简介 图形验证码是一种广泛应用于网络安全认证中的技术,目的是通过对用户输入的图形码进行验证,从而识别人机交互行为是否真实或正常。在Python中,我们可以使用第三方库Pillow(即PIL)和StringIO来实现图片验证码的生成。 2. 环境搭建 在开始之前,需要确保已经配置好了Python的运行环境…

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