首页 > 编程语言 >python中的线程池的了解与学习

python中的线程池的了解与学习

时间:2024-09-09 14:54:27浏览次数:9  
标签:python futures number 学习 factorial 任务 线程 result

文章目录


前言

       线程池是计算机编程中用于管理一组预先创建的线程的机制,这些线程可以被复用以执行多个任务。线程池的主要目的是提高程序的效率和响应性,通过减少线程创建和销毁的开销,以及合理分配线程资源来处理任务。


一、线程池的使用

在Python中,concurrent.futures模块提供了线程池的实现。ThreadPoolExecutor是该模块中用于创建线程池的类。以下是一个使用ThreadPoolExecutor创建线程池并执行任务的例子:

from concurrent.futures import ThreadPoolExecutor

# 创建一个包含5个线程的线程池
pool = ThreadPoolExecutor(5)

# 定义一个函数,该函数将被线程池中的线程执行
def task_function(x):
    return x * x

# 使用线程池执行任务
results = [pool.submit(task_function, i) for i in range(10)]

# 获取所有任务的结果
for future in results:
    print(future.result())

在这个例子中:

  • ThreadPoolExecutor(5)创建了一个包含5个线程的线程池。
  • task_function是一个简单的函数,它将输入值平方。
  • pool.submit(task_function,i)将任务提交给线程池,submit方法返回一个Future对象,可以用来获取任务的结果。
  • 通过future.result()获取每个任务的结果。

再来个例子思考体会一下:

import math
import concurrent.futures


def calculate_factorial(number):
    """计算一个数的阶乘"""
    return math.factorial(number)


def main():
    numbers = [1, 2, 3, 4, 5]  # 任务列表,计算这些数的阶乘

    # 创建一个包含3个线程的线程池
    with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
        # 使用submit函数来提交任务
        futures = {executor.submit(calculate_factorial, number): number for number in numbers}

        # 获取并打印结果
        for future in concurrent.futures.as_completed(futures):
            number = futures[future]
            try:
                result = future.result()
            except Exception as exc:
                print(f"{number} generated an exception: {exc}")
            else:
                print(f"The factorial of {number} is {result}")


if __name__ == "__main__":
    main()

The factorial of 2 is 2
The factorial of 1 is 1
The factorial of 3 is 6
The factorial of 4 is 24
The factorial of 5 is 120

代码解析:

  1. 提交任务:使用executor.submit()方法将任务提交给线程池。submit()方法返回一个Future对象,该对象代表了正在执行的任务。我们使用字典futures来存储Future对象和对应的数字,以便在任务完成后可以找到原始的数字。
  2. 获取结果:使用concurrent.futures.as_completed()函数来迭代已完成的Future对象。当一个任务完成时,我们调用future.result()来获取任务的结果。如果任务执行过程中抛出了异常,result()方法会重新抛出这个异常,我们可以在try…except语句中捕获它。
  3. 处理异常:在try…except语句中,我们检查future.result()是否抛出异常。如果抛出异常,我们打印出异常信息;如果没有异常,我们打印出结果。

使用map函数来提交任务并保持执行顺序

import math
import concurrent.futures


def calculate_factorial(number):
    """计算一个数的阶乘"""
    return math.factorial(number)


def main():
    numbers = [1, 2, 3, 4, 5]  # 任务列表,计算这些数的阶乘

    # 创建一个包含3个线程的线程池
    with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
        # 使用map函数来提交任务并保持执行顺序
        # 使用executor.map()方法将任务提交给线程池。与executor.submit()不同,map()方法会等待所有任务完成,并返回一个结果列表,保持了输入列表的顺序
        results = executor.map(calculate_factorial, numbers)

        # 打印结果
        for number, result in zip(numbers, results):
            print(f"The factorial of {number} is {result}")


if __name__ == "__main__":
    main()

The factorial of 1 is 1
The factorial of 2 is 2
The factorial of 3 is 6
The factorial of 4 is 24
The factorial of 5 is 120

二、线程池的工作流程

  • 当线程数小于核心线程数时,每提交一个任务就创建一个线程来执行,即使当前有线程处于空闲状态,直到当前线程数达到核心线程数
  • 当前线程数达到核心线程数时,如果这个时候还提交任务,这些任务会被放到工作队列里,等到线程处理完了手头的任务后,会从队列中取任务处理。
  • 当前线程数达到核心线程数并且工作队列也满了,如果这个时候还提交任务,则会继续创建线程来处理,直到线程数达到最大线程数。
  • 当前线程数达到最大线程数并且队列也满了,如果这个时候还提交任务,则会触发饱和策略,如抛出异常或拒绝执行任务。

三、线程池的优势

  • 资源消耗降低:通过重复利用已创建的线程,线程池可以降低线程创建和销毁造成的资源消耗。
  • 提高响应速度:当任务到达时,线程池中的线程可以立即执行任务,而无需等待新线程的创建。
  • 提高线程的可管理性:线程是稀缺资源,无限制的创建线程不仅会消耗系统资源,还会降低系统的稳定性。使用线程池可以进行统一分配、调优和监控。

四、总结

通过合理配置线程池的参数,如核心线程数、最大线程数、工作队列大小和饱和策略,可以有效地管理线程资源,提高程序的性能和稳定性。

标签:python,futures,number,学习,factorial,任务,线程,result
From: https://blog.csdn.net/weixin_43574373/article/details/142058049

相关文章

  • 机器学习入门基础:SVD(奇异值分解),看这篇就够了
    本文讲解机器学习的降维部分,包括SVD(奇异值分解)。1.1降维概述1.1.1维数灾难维数灾难(CurseofDimensionality):通常是指在涉及到向量的计算的问题中,随着维数的增加,计算量呈指数倍增长的一种现象。在很多机器学习问题中,训练集中的每条数据经常伴随着上千、甚至上万个特征。要处......
  • 0号线程swapper
    【Linux内核|进程管理】0号线程swapper简介 12人赞同了该文章​目录收起0.说明1.总览2.汇编阶段的初始化3.init_task结构体4.bootcpu0号线程的工作4.1.start_kernel4.2.其他cpu的0号线程创建4.3.......
  • Python3+requests搭建接口自动化测试框架_python3 import requests
    框架理念:使用json文件编写测试用例,建一个脚本循环读取测试用例并执行,然后对比返回的接口和用例中的期望结果。将测试结果写入到一个excel表格中生成测试报告,最后使用发送邮件功能将测试报告发送到指定邮箱。其中对所有公共方法进行封装并放在common公共文件目录下。  ......
  • python接收163邮箱邮件
    importosimportemailimportimaplibimportquopriimportrequestsimportrefromemail.headerimportdecode_headerimportjsonfrompathlibimportPathproject_dir=Path(__file__).resolve().parentimap_host="imap.163.com"email_user=&q......
  • 中移ML307A(4G Cat1,C-SDK,OpenCPU)模组学习开发-使用i2c采集sht30温湿度数据
    <p><iframename="ifd"src="https://mnifdv.cn/resource/cnblogs/ML307A_OPEN"frameborder="0"scrolling="auto"width="100%"height="1500"></iframe></p>  测试1,把文件拷贝到自己工程的 ......
  • 系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践
    本章知识考点:        第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆......
  • C++ 多线程代码性能分析——Oracle Developer Studio工具教程
        最近写项目的时候,为了提升性能,把原来一些单线程的代码改成了并行运行。这里我用到的用于评估性能提升效果的工具是OracleDeveloperStudio,不过刚上手时,发现网上相关的教程和博客较少,有些功能的使用也是摸索着过来的,这一过程可谓是十分痛苦了……如今距离初次接触......
  • Python将表格文件中某些列的数据整体向上移动一行
      本文介绍基于Python语言,针对一个文件夹下大量的Excel表格文件,对其中的每一个文件加以操作——将其中指定的若干列的数据部分都向上移动一行,并将所有操作完毕的Excel表格文件中的数据加以合并,生成一个新的Excel文件的方法。  首先,我们明确一下本文的需求。在一个文件夹内,有......
  • 推荐一个Python流式JSON处理模块:streaming-json-py
    每天,我们的设备、应用程序和服务都在生成大量的数据流,这些数据往往大多是以JSON格式存在的。如何高效地解析和处理这些JSON数据流是一大挑战。今天,我要为大家介绍一个能极大简化这一过程的利器:streaming-json-pystreaming-json-py介绍streaming-json-py是一个专为实时......
  • golang中关于死锁的思考与学习
    1、Golang中死锁的触发条件1.1书上关于死锁的四个必要条件的讲解发生死锁时,线程永远不能完成,系统资源被阻碍使用,以致于阻止了其他作业开始执行。在讨论处理死锁问题的各种方法之前,我们首先深入讨论一下死锁特点。必要条件:如果在一个系统中以下四个条件同时成立,那么就能引起死......