返回顶部
首页 > 资讯 > 后端开发 > Python >浅谈一下python线程池简单应用
  • 677
分享到

浅谈一下python线程池简单应用

python线程池python线程池应用 2023-05-16 15:05:22 677人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

一、线程池简介 传统多线程方案会使用“即时创建,即时销毁”的策略。尽管与创建进程相比,创建线程的时间已经大大的缩短,但是如果提交给线程的任务时执行时间较短,而

一、线程池简介

传统多线程方案会使用“即时创建,即时销毁”的策略。尽管与创建进程相比,创建线程的时间已经大大的缩短,但是如果提交给线程的任务时执行时间较短,而且执行次数及其频繁,那么服务器将处于不停的创建线程,销毁线程的状态。

一个线程的运行时间可以分为三部分:线程的启动时间、线程体的运行时间和线程的销毁时间。

在多线程处理的情景中,如果线程不能被重用,就意味着每次线程运行都要经过启动、销毁和运行3个过程。这必然会增加系统相应的时间,减低了效率。

线程池在系统启动时即创建大量空闲的线程,程序只要将一个函数提交给线程池,线程池就会启动一个空闲的线程来执行它。

当该函数执行结束后,该线程并不会死亡,而是再次返回到线程池中变成空闲状态,等待执行下一个函数,因此能够避免多次创建线程,从而节省线程创建和销毁的开销,能带来更好的性能和稳定性。

此外,使用线程池可以有效地控制系统中并发线程的数量。当系统中包含有大量的并发线程时,会导致系统性能急剧下降,甚至导致python解释器崩溃,而线程池的最大线程数参数可以控制系统中并发线程的数量不超过此数。

服务器CPU数有限,能够同时并发的线程数有限,并不是开得越多越好,以及线程切换时有开销的,如果线程切换过于频繁,反而会使性能降低。

线程池适用于:突发性大量请求或需要大量线程完成任务,但实际任务处理时间较短的场景

二、线程池在Python中的应用

python3.2开始,标准库提供了concurrent.futures模块,它提供了两个子类:ThreadPoolExecutor和ProcessPoolExecutor。其中ThreadPoolExecutor用于创建线程池,而ProcessPoolExecutor用于创建进程池。不仅可以自动调度线程,还可以做到:

  • 主线程可以获取某一个线程(或任务)的状态,以及返回值
  • 当一个线程完成的时候,主线程能够立即知道
  • 让多线程和多进程编码接口一致

使用线程池/进程池来管理并发编程,只要将相应的 task 函数提交给线程池/进程池,剩下的事情就由线程池/进程池来搞定。

ThreadPoolExecutor构造函数有两个参数:

一个是max_workers参数,用于指定线程池的最大线程数,如果不指定的话则默认是CPU核数的5倍。

另一个参数是thread_name_prefix,它用来指定线程池中线程的名称前缀(可选),如下:

threadPool = ThreadPoolExecutor(max_workers=self.max_workers, thread_name_prefix="test_")

Exectuor 提供了如下常用方法:

方法描述
submit(fn, *args, **kwargs)将 fn 函数提交给线程池。*args 代表传给 fn 函数的参数,**kwargs 代表以关键字参数的形式为 fn 函数传入参数
map(func,*iterables, timeout=None, chunksize=1)该函数类似于全局函数 map(func, *iterables),只是该函数将会启动多个线程,以异步方式立即对 iterables 执行 map 处理
shutdown(wait=True)关闭线程池。wait=True,等待池内所有任务执行完毕回收完资源后才继续;wait=False,立即返回,并不会等待池内的任务执行完毕。但不管wait参数为何值,整个程序都会等到所有任务执行完毕

程序将 task 函数提交(submit)给线程池后,submit 方法会返回一个 Future 对象,Future 类主要用于获取线程任务函数的返回值。由于线程任务会在新线程中以异步方式执行,因此线程执行的函数相当于一个“将来完成”的任务,所以 Python 使用 Future 来代表。

Future 提供了如下方法:

方法描述
cancel()取消该 Future 代表的线程任务。如果该任务正在执行,不可取消,则该方法返回 False;否则,程序会取消该任务,并返回 True
cancelled()返回 Future 代表的线程任务是否被成功取消
running()如果该 Future 代表的线程任务正在执行、不可被取消,该方法返回 True
done()如果该 Funture 代表的线程任务被成功取消或执行完成,则该方法返回 True
result(timeout=None)获取该 Future 代表的线程任务最后返回的结果。如果 Future 代表的线程任务还未完成,该方法将会阻塞当前线程,其中 timeout 参数指定最多阻塞多少秒
exception(timeout=None)获取该 Future 代表的线程任务所引发的异常。如果该任务成功完成,没有异常,则该方法返回 None
add_done_callback(fn)为该 Future 代表的线程任务注册一个“回调函数”,当该任务成功完成时,程序会自动触发该 fn 函数

线程池用完后,应调用线程池的shutdown()方法,关闭线程池。也可使用with语句来管理线程池,可避免手动关闭线程池

示例一(使用submit方式):

from concurrent.futures import ThreadPoolExecutor # 导入ThreadPoolExecutor模块
import time
 
max_workers = 5
t = []
t1 = time.time()
 
# 作为线程任务的函数
def task(x, y):
    return x + y
 
threadPool = ThreadPoolExecutor(max_workers)    # 创建最大线程数为max_workers的线程池
 
for i in range(20):     # 循环向线程池中提交task任务
    future = threadPool.submit(task, i, i+1)
    t.append(future)
 
# 若不需要获取返回值,则可不需要下面两行代码
for i in t:
    print(i.result())   # 获取每个任务的返回值,result()会阻塞主线程
 
threadPool.shutdown()   # 阻塞主线程,所有任务执行完后关闭线程池
print(time.time() - t1)

示例二(使用map方式):

from concurrent.futures import ThreadPoolExecutor	# 导入ThreadPoolExecutor模块
 
max_workers = 5
t = []
t1 = time.time()
 
# 作为线程任务的函数
def task(x):
    return x + (x + 1)
 
args = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
 
with ThreadPoolExecutor(max_workers) as threadPool:   # 创建最大线程数为max_workers的线程池
    results = threadPool.map(task, args)    # 启动线程,并收集每个线任务的返回结果
 
    # 若无返回值,则可不需要下面两行代码
    for i in results:
        print(i)   

示例三:

as_complete():是一个生成器,在没有任务完成的时候会阻塞,在有某个任务完成的时候会yield这个任务,执行语句,继续阻塞,循环到所有任务结束,先完成的任务会先通知主线程

from concurrent.futures import ThreadPoolExecutor, as_completed
import time
 
max_workers = 5
t = []
t1 = time.time()
 
# 作为线程任务的函数
def task(x, y):
    return x + y
 
def handle_result(future):
    print(future.result())
 
with ThreadPoolExecutor(max_workers) as threadPool:    # 创建最大线程数为max_workers的线程池
 
    for i in range(20):     # 循环向线程池中提交task任务
        future = threadPool.submit(task, i, i+1)
        t.append(future)
 
    # 若不需要获取返回值,则可不需要下面两行代码
    for future in as_completed(t):  # as_completed,哪个先完成就先处理哪个,会阻塞主线程,直到完成所有,除非设置timeout
        future.add_done_callback(handle_result)

到此这篇关于浅谈一下python线程池简单应用的文章就介绍到这了,更多相关python线程池简单应用内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 浅谈一下python线程池简单应用

本文链接: https://lsjlt.com/news/210176.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 浅谈一下python线程池简单应用
    一、线程池简介 传统多线程方案会使用“即时创建,即时销毁”的策略。尽管与创建进程相比,创建线程的时间已经大大的缩短,但是如果提交给线程的任务时执行时间较短,而...
    99+
    2023-05-16
    python线程池 python线程池应用
  • 简单谈谈ThreadPoolExecutor线程池之submit方法
    jdk1.7.0_79 在上一篇《ThreadPoolExecutor线程池原理及其execute方法》中提到了线程池ThreadPoolExecutor的原理以及它的execute方法。本文解析ThreadPoolExecutor#sub...
    99+
    2023-05-31
    线程池 submit threadpoolexecutor
  • 浅谈python 线程池threadpool之实现
    首先介绍一下自己使用到的名词: 工作线程(worker):创建线程池时,按照指定的线程数量,创建工作线程,等待从任务队列中get任务; 任务(requests):即工作线程处理的任务,任务可能成千上万个,但...
    99+
    2022-06-04
    浅谈 线程 python
  • 用Python实现一个简单的线程池
    线程池的概念是什么?在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是 如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能...
    99+
    2023-01-31
    线程 简单 Python
  • 浅谈一下Java线程组ThreadGroup
    目录1 简介2 线程组树的结构3 线程组的构造4 API5 终止线程组中的所有线程1 简介 一个线程集合。是为了更方便地管理线程。父子结构的,一个线程组可以集成其他线程组,同时也可以...
    99+
    2023-05-19
    Java 线程组 Java ThreadGroup
  • 浅谈Android 的线程和线程池的使用
    Android 的线程和线程池从用途上分,线程分为主线程和子线程;主线程主要处理和界面相关的事情,子线程则往往用于耗时操作。主线程和子线程主线程是指进程所拥有的线程。Android 中主线程交 UI 线程,主要作用是运行四大组件以及处理它们...
    99+
    2023-05-30
    android 线程池 roi
  • python浅谈一下线程间通信之队列
    目录为什么需要线程间通信线程间通信方式有哪些线程间通信案例之队列总结为什么需要线程间通信 一个人的力量是有限的,但是团队合作可以发挥更大的作用。而团队协作需要交流和通信来有效的分配任...
    99+
    2023-05-17
    Python线程通信 Python线程通信队列 python队列
  • 浅谈一下Java的线程并发
    谈到并发,必会涉及操作系统中的线程概念,线程是CPU分配的最小单位,windows系统是抢占式的,linux是轮询式的,都需要获取CPU资源。并行:同一时刻,两个线程都在执行。并发:...
    99+
    2024-04-02
  • 简单探讨一下python线程锁
    目录为什么需要线程锁线程锁使用案例说明线程锁实现一个读写锁总结为什么需要线程锁 当我们访问一些特殊的数据时,需要保证该数据的原子性,比如: 文章的阅读量、文章的点赞量等。我们必须要确...
    99+
    2023-05-17
    python 线程锁
  • 简单聊一聊Java线程池ThreadPoolExecutor
    目录简介参数说明如何创建线程池拒绝策略总结简介 ThreadPoolExecutor是一个实现ExecutorService接口的线程池,ExecutorService是主要用来处理...
    99+
    2024-04-02
  • 浅谈一下Java多线程断点复制
    目录细节介绍代码部分定时任务类记录信息类复制线程类复制工具类总结上次写了一个利用 RandomAccessFile 和 多线程实现的多线程复制,但是没有增加断点复制的功能。这里的断点...
    99+
    2023-05-15
    Java多线程 Java断点 Java断点复制
  • 浅谈Spring @Async异步线程池用法总结
    本文介绍了Spring @Async异步线程池用法总结,分享给大家,希望对大家有帮助1. TaskExecutorspring异步线程池的接口类,其实质是Java.util.concurrent.ExecutorSpring 已经实现的异常...
    99+
    2023-05-31
    async spring 线程池
  • 浅谈python 里面的单下划线与双下划线的区别
    在学习Python的时候,很多人都不理解为什么在方法(method)前面会加好几个下划线,有时甚至两边都会加,比如像 __this__ 这种。在我看到上面的文章之前,我一直以为Python中这些下划线的作用...
    99+
    2022-06-04
    下划线 浅谈 区别
  • 浅谈一下Python中的with用法
    目录一、With语句是什么二、with如何工作三、相关术语一、With语句是什么 有一些任务,可能事先需要设置,事后做清理工作。对于这种场景,Python的with语句提供了一种非常...
    99+
    2023-05-15
    Python with Python with用法
  • C++怎么实现一个简单的线程池
    本文小编为大家详细介绍“C++怎么实现一个简单的线程池”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++怎么实现一个简单的线程池”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、设计线程池应该包括保存线程的容...
    99+
    2023-06-30
  • 浅谈python字符串方法的简单使用
    学习python字符串方法的使用,对书中列举的每种方法都做一个试用,将结果记录,方便以后查询。 (1) s.capitalize() ;功能:返回字符串的的副本,并将首字母大写。使用如下: >&g...
    99+
    2022-06-04
    浅谈 字符串 简单
  • java实现手写一个简单版的线程池
    有些人可能对线程池比较陌生,并且更不熟悉线程池的工作原理。所以他们在使用线程的时候,多数情况下都是new Thread来实现多线程。但是,往往良好的多线程设计大多都是使用线程池来实现...
    99+
    2024-04-02
  • python 进程池的简单使用方法
    回到python,用一下python的进程池。 记得之前面试的时候,面试官问:你知道进程池的默认参数吗? 我没有回答上来,后来才知道,是有默认参数的。下面就看看它的默认参数 1. 不加参数 from multiprocessing.po...
    99+
    2023-01-30
    使用方法 进程 简单
  • C++实现一个简单的线程池的示例代码
    目录一、设计二、参数选择三、类设计一、设计 线程池应该包括 保存线程的容器,保存任务的容器。为了能保证避免线程对任务的竞态获取,需要对任务队列进行加锁。为了使得工作线程感知任务的到来...
    99+
    2024-04-02
  • Java线程池的简单使用方法实例教程
    目录线程池使用场景? Java线程池使用总结线程池使用场景? java中经常需要用到多线程来处理一些业务,我们非常不建议单纯使用继承Thread或者实现Runnable接口...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作