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日

相关文章

  • Tips of Pycharm快捷键 Python开发工具PyCharm快捷键使用汇总

    Tips of Pycharm快捷键 Python开发工具PyCharm快捷键使用汇总 PyCharm是一款流行的Python集成开发环境,具有许多实用的功能和快捷键。这里汇总了一些常用的快捷键和功能,希望对Python开发者有所帮助。 快捷键 导航 Ctrl + N:在项目中查找类 Ctrl + Shift + N:在项目中查找文件 Ctrl + Alt …

    python 2023年6月5日
    00
  • Python help()函数用法详解

    Python help()函数用法详解 简介 Python中内置的help()函数是一个很有用的工具,它可以提供对象的帮助文档,包括对象的方法和属性。当你在开发Python程序时,很有可能需要查看某个函数、模块或类的文档,这个时候就可以使用help()函数来获取这些信息。 用法 help()函数的使用非常简单,只需要将要查看帮助文档的对象作为参数传递给hel…

    python 2023年6月5日
    00
  • 详解Python 跟踪使用情况

    Python提供了内置的模块tracemalloc来跟踪Python程序的内存使用情况。 使用tracemalloc模块可以获得Python程序中对象分配的具体位置以及分配对象的大小等详细信息。 下面就是使用tracemalloc模块的完整攻略,完整示例代码如下: 导入 required 模块 import tracemalloc 开始跟踪内存分配 trac…

    python-answer 2023年3月25日
    00
  • 100 个 Python 小例子(练习题三)

    100个 Python 小例子(练习题三)攻略 “100个 Python 小例子(练习题三)”是一系列Python编程练习题,旨在帮助Python初学者提高编程技能。本文将为您提供该练习题的完整攻略,包括题目描述、解题思路和代码实现。以下是两个示例说明: 示例一:计算字符串中每个单词出现的次数 题目描述 编写一个Python程序计算给定字符串中每个单词出现的…

    python 2023年5月13日
    00
  • python工具模块介绍-time 时间访问和转换

    快速入门 In [1]: import time # 获取当前时间 In [25]: time.strftime(“%Y-%m-%d_%H-%M-%S”, time.localtime()) Out[25]: ‘2018-06-17_20-05-36’ # 停顿0.5秒 In [26]: time.sleep(0.5) 简介 功能:时间访问和转换。 相关模块…

    python 2023年4月25日
    00
  • python判断列表的连续数字范围并分块的方法

    要判断列表中的连续数字范围并分块,可以利用python中的迭代器和列表解析。以下是详细攻略: 使用zip和迭代器来判断连续数字范围 定义一个获取连续数字范围的迭代器函数range_by_increment: from typing import List def range_by_increment(nums: List[int]): i = iter(nu…

    python 2023年5月14日
    00
  • Python字典实现伪切片功能

    Python 中的字典没有类似于列表或字符串那样的切片功能。但是,我们可以通过使用 itertools.islice() 和字典的键来实现类似于切片的功能。下面是实现这一功能的完整攻略。 第一步:导入必要的模块 itertools.islice()是我们需要的主要模块,因此我们需要导入它。 import itertools 第二步:创建字典 我们需要一个字典…

    python 2023年5月13日
    00
  • Python实现针对json中某个关键字段进行排序操作示例

    我来为你详细讲解“Python实现针对json中某个关键字段进行排序操作”的攻略。 一、分析需求 在进行操作之前,需要先明确需求。我们需要实现针对json中某个关键字段进行排序的操作,即按某个字段的值大小或字典序对json进行排序。 二、准备工作 在进行操作之前,需要先安装json模块: import json 然后,我们需要有一个待排序的json数据,例如…

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