当前位置: 首页 > news >正文

python线程池

假设我们必须多线程任务创建大量线程。 由于线程太多,因此可能会有很多性能问题,这在计算上会是最昂贵的。 一个主要问题可能是吞吐量受限。 我们可以通过创建一个线程池来解决这个问题。 一个线程池可以被定义为一组预先实例化和空闲的线程,它们随时可以开始工作。 创建线程池比我们需要执行大量任务时为每个任务实例化新线程更受欢迎。 线程池可以管理大量线程的并发执行,如下所示 -

  • 如果线程池中的线程完成其执行,那么该线程可以被重用。
  • 如果一个线程被终止,另一个线程将被创建以替换该线程。

Python模块 - Concurrent.futures

Python标准库包含concurrent.futures模块。 这个模块是在Python 3.2中添加的,为开发人员提供了启动异步任务的高级接口。 它是Python的线程和多处理模块的顶层的一个抽象层,用于提供使用线程或进程池运行任务的接口。
在后面的章节中,我们将学习concurrent.futures模块中的类。

执行者类

Executor是一个 Python concurrent.futures模块的抽象类。 它不能直接使用,我们需要使用以下具体子类之一 -

  • ThreadPoolExecutor
  • ProcessPoolExecutor
ThreadPoolExecutor -

一个具体的子类它是Executor类的具体子类之一。 子类使用多线程,我们得到一个提交任务的线程池。 该池将任务分配给可用线程并安排它们运行。

如何创建一个ThreadPoolExecutor?

在concurrent.futures模块及其具体子类Executor的帮助下,可以很容易地创建一个线程池。 需要使用我们想要的池中的线程数构造一个ThreadPoolExecutor。 默认情况下,数字是5。然后可以提交一个任务到线程池。 当submit()任务时,会返回Future对象。 Future对象有一个名为done()的方法,它告诉Future是否已经解决。 有了这个,为这个特定的Future对象设定了一个值。 当任务完成时,线程池执行器将该值设置为Future的对象。
示例代码

from concurrent.futures import ThreadPoolExecutor
from time import sleep
def task(message):sleep(2)return messagedef main():executor = ThreadPoolExecutor(5)future = executor.submit(task, ("Completed"))print(future.done())sleep(2)print(future.done())print(future.result())
if __name__ == '__main__':
main()

执行上面示例代码,得到以下结果 -

False
True
Completed

在上面的例子中,一个ThreadPoolExecutor已经由5个线程构造而成。 然后,在提供消息之前等待2秒的任务被提交给线程池执行器。 从输出中可以看出,任务直到2秒才完成,所以第一次调用done()将返回False。 2秒后,任务完成,我们通过调用result()方法得到future的结果

实例化ThreadPoolExecutor

上下文管理器另一种实例化ThreadPoolExecutor的方法是在上下文管理器的帮助下完成的。 它的工作方式与上例中使用的方法类似。 使用上下文管理器的主要优点是它在语法上看起来不错。 实例化可以在下面的代码的帮助下完成 -

with ThreadPoolExecutor(max_workers = 5) as executor
示例

以下示例是从Python文档借用的。 在这个例子中,首先必须导入concurrent.futures模块。 然后创建一个名为load_url()的函数,它将加载请求的url。 然后该函数用池中的5个线程创建ThreadPoolExecutor。 ThreadPoolExecutor已被用作上下文管理器。 我们可以通过调用result()方法来获得future的结果

import concurrent.futures
import urllib.requestURLS = ['http://www.foxnews.com/','https://www.yiibai.com/','http://europe.wsj.com/','http://www.bbc.co.uk/','http://some-made-up-domain.com/']def load_url(url, timeout):with urllib.request.urlopen(url, timeout = timeout) as conn:return conn.read()with concurrent.futures.ThreadPoolExecutor(max_workers = 5) as executor:future_to_url = {executor.submit(load_url, url, 60): url for url in URLS}for future in concurrent.futures.as_completed(future_to_url):url = future_to_url[future]try:data = future.result()except Exception as exc:print('%r generated an exception: %s' % (url, exc))else:print('%r page is %d bytes' % (url, len(data)))

以下将是上面的Python脚本的输出 -

'http://some-made-up-domain.com/' generated an exception: <urlopen error [Errno 11004] getaddrinfo failed>
'http://www.foxnews.com/' page is 229313 bytes
'http://www.yiibai.com/' page is 168933 bytes
'http://www.bbc.co.uk/' page is 283893 bytes
'http://europe.wsj.com/' page is 938109 bytes
使用Executor.map()

函数Python map()函数广泛用于许多任务。 一个这样的任务是对可迭代内的每个元素应用某个函数。 同样,可以将迭代器的所有元素映射到一个函数,并将这些作为独立作业提交到ThreadPoolExecutor之外。 考虑下面的Python脚本示例来理解函数的工作原理。

示例

在下面的示例中,map函数用于将square()函数应用于values数组中的每个值。

from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import as_completed
values = [2,3,4,5]
def square(n):return n * n
def main():with ThreadPoolExecutor(max_workers = 3) as executor:results = executor.map(square, values)for result in results:print(result)
if __name__ == '__main__':main()

以下将是上面的Python脚本的输出 -

4
9
16
25
http://www.lryc.cn/news/35303.html

相关文章:

  • 深入浅出PaddlePaddle函数——paddle.ones_like
  • 计算机组成原理(海明码效验)(3)-软件设计(二十四)
  • Linux2.2网络驱动程序编写
  • 像素密度提升33%,Quest Pro动态注视点渲染原理详解
  • 【Linux实战篇】二、在Linux上部署各类软件
  • 基于SpringBoot的学生会管理系统 源码
  • [league/glide]两行代码实现一套强大的图片处理HTTP服务
  • Kafka 消费者组
  • 高效学 C++|组合类的构造函数
  • Java使用Springboot+Mybatis构建第一个项目
  • L2-007 家庭房产 L1-007 念数字
  • 1/4、1/2、整车悬架天棚主动控制仿真分析合集
  • 【微信小程序项目实战】TodoList-项目主体搭设(2)
  • 23种设计模式-迭代器模式(安卓应用场景介绍)
  • 面试 - 软件工程体系
  • 05-CSS
  • 华为OD机试题,用 Java 解【分奖金】问题
  • Multisim 14.3 安装教程
  • 06-Oracle表空间与用户管理(表空间,用户,备份与恢复,导入导出数据)
  • XSS攻击防御
  • 敏捷开发还需要PRD吗
  • 完整教程:使用Spring Boot实现大文件断点续传及文件校验
  • 数位dp-- 数字游戏
  • Linux脚本 启动、重启、停止、授权
  • Pytorch深度学习实战3-8:详解数据可视化组件TensorBoard安装与使用
  • 华为OD机试 - 旋转骰子(C 语言解题)【独家】
  • 如何做SpringBoot单元测试?
  • ZZULI训练: 数组和字符串专题
  • ElasticSearch如何解决深分页问题?
  • JDK8新特性宝典