Python线程池thread pool创建使用及实例代码分享

yizhihongxing

Python线程池thread pool创建使用及实例代码分享

Python线程池(thread pool)是一种提供线程复用的机制,通过线程池的管理,可以减少线程创建与销毁的代价,并提升异步并发执行的性能,同时避免资源的浪费,使用起来也相对方便和稳定。本篇攻略将详细介绍如何在Python中使用线程池,通过实例代码的分享帮助读者更好的掌握线程池的使用和工作原理。

创建线程池

Python内置了线程池的支持,使用concurrent.futures模块中的ThreadPoolExecutor类可以方便地创建线程池。

首先,需要导入concurrent.futures模块,以及time模块用于辅助时间计算。

import concurrent.futures
import time

然后,可以通过如下方式创建一个具有4个线程的线程池。

with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
    # TODO: 任务列表

可以看到,在创建线程池时,可以通过max_workers参数指定线程池中线程的数量,具体数量应该根据具体的场景来确定。同时,在使用完线程池后,需要使用with语句来自动管理线程池的资源。

提交任务

线程池中的工作线程需要执行的任务通过提交操作放入线程池中,线程池会自动选择适当的线程来执行任务。一般情况下,任务都是使用函数的形式传递给线程池。

举个例子,假设有一个需要执行的计算任务,可以通过如下方式定义计算函数。

def compute(num):
    result = num * num
    time.sleep(1)  # 模拟耗时操作
    return result

该函数接收一个参数num,返回num的平方,并使用time.sleep函数模拟耗时操作。

接下来,可以通过使用submit方法将任务提交到线程池中。

with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
    future_list = []
    for i in range(10):
        future = executor.submit(compute, i)
        future_list.append(future)

可以看到,在遍历任务列表时,可以使用submit方法将任务提交到线程池中,并使用future_list保存任务的结果。submit方法的第一个参数是需要执行的函数,后续的参数是函数的输入参数。

获取结果

线程池中的任务是异步执行的,因此主线程需要使用future对象来获取线程执行的结果。future对象对应一个线程任务,其中包含了线程执行结果和执行状态等参数。

可以使用done方法判断任务是否已经完成,使用result方法获取任务的返回值,如下所示。

with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
    future_list = []
    for i in range(10):
        future = executor.submit(compute, i)
        future_list.append(future)

    for future in concurrent.futures.as_completed(future_list):
        if future.done():
            print("result: {}".format(future.result()))

可以看到,在使用as_completed方法迭代线程任务时,可以使用future.done()方法判断线程是否执行完,使用future.result()方法获取线程执行结果。

示例说明1:异步下载图片

假设要异步下载多张图片并保存到本地,可以通过使用线程池实现,具体步骤如下。

首先,需要导入requests模块和os模块,后者用于保存图片。

import requests
import os

然后,可以定义下载函数,将图片和本地文件名作为输入参数。

def download_img(url, filename):
    response = requests.get(url, stream=True)
    with open(filename, 'wb') as f:
        for chunk in response.iter_content(1024):
            f.write(chunk)

注意,download_img函数将使用requests.get方法下载图片内容,并使用stream=True参数设置为分块读取,以便在下载大文件时不会占用太多内存。下载完成后,将图片内容保存到指定的文件中。

接下来,可以通过使用线程池,并构造许多下载任务来完成异步下载图片的工作。

with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
    urls = ["https://picsum.photos/200/300?random={}".format(i) for i in range(10)]
    filenames = [os.path.join(os.getcwd(), "img{}.jpg".format(i)) for i in range(10)]

    future_list = []
    for i in range(10):
        future = executor.submit(download_img, urls[i], filenames[i])
        future_list.append(future)

    for future in concurrent.futures.as_completed(future_list):
        if future.done():
            print("download {} complete".format(future.args[1]))

在上面的代码中,首先构造了10个图片的URL和下对应的文件名,并使用线程池构造了10个下载任务,并将任务的future对象保存在列表中。随后,可以使用as_completed方法依次判断并输出每个任务的状态。

示例说明2:并发执行多个命令

假设要在本地同时执行多个操作系统命令,并等待所有命令执行完成后再输出相应结果,可以通过使用线程池实现。

首先,需要将命令列表构造出来。

commands = ['echo Hello', 'echo World', 'ls -l']

然后,定义命令执行函数。

def run_command(command):
    print("Running command: {}".format(command))
    result = os.popen(command).read()
    time.sleep(1)  # 模拟耗时操作
    return result

在该函数中,首先输出将要执行的命令,然后使用os.popen执行相应命令,并将执行结果保存到返回值中。

然后,可以通过使用线程池,并构造许多命令执行任务来完成异步执行命令的工作。

with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
    future_list = []
    for command in commands:
        future = executor.submit(run_command, command)
        future_list.append(future)

    for future in concurrent.futures.as_completed(future_list):
        if future.done():
            print("result: {}".format(future.result()))

在上述代码中,首先构造了命令列表,并使用线程池构造了多个命令任务,并将任务的future对象保存在列表中。随后,可以使用as_completed方法依次判断并输出每个任务的执行结果。

总结

Python线程池提供了高效的管理方式和执行异步任务的能力,同时使用也非常简单明了,可以极大提升代码的执行效率和并行性。通过上述示例,相信读者已经对Python线程池有了一定的了解,可以在实际项目中灵活应用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python线程池thread pool创建使用及实例代码分享 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • python 检查文件mime类型的方法

    当我们需要确定一个文件的类型时,可以采用MIME类型来进行检查。MIME类型是一种由多用途互联网邮件扩展(MIME)引入的标准。它是一种用来标识文件格式的字符串,通常由文件的后缀名来确定。 在Python中,使用mimetypes模块可以进行MIME类型检查。下面是如何使用mimetypes进行文件MIME类型检查的完整攻略: 1. 导入mimetypes模…

    python 2023年5月20日
    00
  • python实现的登录和操作开心网脚本分享

    开心网是一个中国社交网络平台,本文将详细讲解如何使用Python实现登录和操作开心网的完整攻略,包括使用requests库发送HTTP请求和处理HTTP响应、使用BeautifulSoup库解析HTML文档、使用selenium库模拟浏览器操作等。 登录开心网 在Python中,我们可以使用requests库发送HTTP POST请求模拟登录开心网。以下是一…

    python 2023年5月15日
    00
  • python出现RuntimeError错误问题及解决

    当我们在Python编程过程中,有时会遇到RuntimeError的报错。这通常是由于程序运行时出现了异常或错误,导致程序无法正常执行。以下是些常见的RuntimeError错的解决方案: 1. 检查代码逻辑 如果在Python编程过程中遇到了类似以下的报错: RuntimeError: maximum recursion depth exceeded 这说…

    python 2023年5月13日
    00
  • python调试器中的所有变量都未定义

    【问题标题】:all variables are undefined in python debuggerpython调试器中的所有变量都未定义 【发布时间】:2023-04-03 06:54:01 【问题描述】: 我在 Python 3.6 上遇到了一个非常奇怪的问题。在我的代码中间,我调用import pdb; pdb.set_trace() 来调试一些…

    Python开发 2023年4月8日
    00
  • 一个可以套路别人的python小程序实例代码

    针对“一个可以套路别人的python小程序实例代码”的完整攻略,我将按照以下步骤来讲解: 需求分析:确定小程序的功能和实现要求 编写伪代码:根据需求分析,编写伪代码 编写代码:根据伪代码,编写实际代码 测试和调试:对代码进行测试和调试,确保程序运行正常 下面我将详细讲解每个步骤的内容。 1. 需求分析 在进行编码前,首先需要确定小程序的功能和实现要求。根据该…

    python 2023年5月23日
    00
  • Python按键或值对字典进行排序

    下面是Python按键或值对字典进行排序的完整攻略: 按键(key)排序 可以利用Python的内置函数sorted()和字典的items()方法对字典中的键(key)进行排序。具体步骤如下: 使用items()方法把字典转为元组列表,形式为[(key1, value1), (key2, value2), …]。 使用sorted()函数对元组列表进行排…

    python 2023年5月13日
    00
  • 如何用python做逐步回归

    以下是使用Python进行逐步回归的完整攻略,包括定义逐步回归、如何使用Python进行逐步回归以及两个具体的示例。 定义逐步回归 逐步回归是一种特殊的回归分析方法,用于处理多元回归分析中的变量选择问题。与其他回归分析方法不同,逐步回归算法从包含所有可能的解释变量的初始模型开始,每次只将一个解释变量添加到模型中,当该解释变量满足一定的标准(例如显著性水平)时…

    python 2023年5月14日
    00
  • Python 多线程爬取案例

    Python多线程爬取案例的完整攻略如下: 1. 多线程爬取网页内容 以下是一个示例,演示如何使用Python多线程爬取网页内容: import requests import threading def get_url_content(url): response = requests.get(url) print(response.content) if…

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