python并发编程: Python好用的线程池ThreadPoolExecutor

本文涉及的产品
实时数仓Hologres,5000CU*H 100GB 3个月
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
大数据开发治理平台 DataWorks,不限时长
简介: python并发编程: Python好用的线程池ThreadPoolExecutor

往期文章:

  1. 并发编程简介
  2. 怎样选择多线程多进程多协程
  3. Python速度慢的罪魁祸首,全局解释器锁GIL
  4. 使用多线程,Python爬虫被加速10倍
  5. Python实现生产者消费者爬虫
  6. Python线程安全问题以及解决方案

线程池概念介绍

上图左侧是展示的是一个线程的生命周期,首先,新建线程,然后准备就绪,等cpu调用,如果被调用,则开始运行,如果被切换,则又返回就绪状态,如果是因为io或者sleep,则进入阻塞状态,阻塞结束则又回到就绪状态,反反复复,直到执行完。之所以要采用线程池,右上角以说明原因。

线程池的好处:

  • 提升性能:因为减去了大量新建、终止线程的开销,重用了线程资源;
  • 适用场景:适合处理突发性大量请求或需要大量线程完成任务、但实际任务处理时间较短
  • 防御功能:能有效避免系统因为创建线程过多,而导致系统负荷过大相应变慢等问题
  • 代码优势:使用线程池的语法比自己新建线程执行线程更加简洁

线程池的使用方法

  • 用法一: map函数,很简单。
    ```python
    from concurrent.futures import ThreadPoolExecutor,as_completed

with ThreadPoolExecutor() as pool:
results = pool.map(craw,urls)
for result in results:
print(result)


> 注意map的结果和入参是顺序对应的。


- 用法二: futures模式,更强大。

```python
from concurrent.futures import ThreadPoolExecutor,as_completed

with ThreadPoolExecutor() as pool:
     futures = [ pool.submit(craw,url)  for url in urls]

     for future in futures:
        print(future.result())

     for future in as_completed(futures):
        print(future.result())

注意如果用as_completed顺序是不定的。

使用线程池改造爬虫程序

import concurrent.futures
import cnblogs_spider


#craw 
with concurrent.futures.ThreadPoolExecutor() as pool:
    htmls = pool.map(cnblogs_spider.craw,cnblogs_spider.urls)
    htmls = list(zip(cnblogs_spider.urls,htmls))
    for url,html in htmls:
        print(url,len(html))

#parse
with concurrent.futures.ThreadPoolExecutor() as pool:
    futures = {
   
   }
    for url,html in htmls:
        future = pool.submit(cnblogs_spider.parse,html)
        futures[future] = url

    #for future,url in futures.items():
    #    print(url,future.result())
    for future in concurrent.futures.as_completed(futures):
        url = futures[future]
        print(url,future.result())
目录
相关文章
|
5天前
|
Java 开发者
Java面试题:请解释内存泄漏的原因,并说明如何使用Thread类和ExecutorService实现多线程编程,请解释CountDownLatch和CyclicBarrier在并发编程中的用途和区别
Java面试题:请解释内存泄漏的原因,并说明如何使用Thread类和ExecutorService实现多线程编程,请解释CountDownLatch和CyclicBarrier在并发编程中的用途和区别
10 0
|
4天前
|
数据采集 数据库 Python
Python并发编程新篇章:asyncio库使用全攻略,轻松驾驭异步世界!
【7月更文挑战第11天】Python的asyncio开启异步编程时代,通过案例展示如何用它和aiohttp构建并发爬虫。安装aiohttp后,定义异步函数`fetch`进行HTTP请求,返回状态码和内容长度。在`main`中,并发执行多个`fetch`任务,利用`asyncio.gather`收集结果。使用`async with`管理HTTP会话资源,确保释放。通过这种方式,爬虫性能大幅提升,适用于高并发场景。学习asyncio是提升并发性能的关键。
28 14
|
1天前
|
消息中间件 安全 数据处理
Python中的并发编程:理解多线程与多进程的区别与应用
在Python编程中,理解并发编程是提高程序性能和响应速度的关键。本文将深入探讨多线程和多进程的区别、适用场景及实际应用,帮助开发者更好地利用Python进行并发编程。
|
2天前
|
缓存 并行计算 监控
了解 Python 线程
【7月更文挑战第8天】在Python多线程编程中,`threading`模块允许我们获取当前线程名字,通过`current_thread().name`获取。线程名字有助于调试、日志和资源管理。示例代码展示了如何创建线程并打印其名字。在实际应用中,线程命名应清晰、唯一且避免特殊字符,以提高代码可读性和维护性。多线程编程需注意线程安全、死锁、性能优化等问题。通过合理设计和测试,可以利用多线程提高程序并发性和效率。
6 1
|
5天前
|
数据库 数据安全/隐私保护 C++
Python并发编程实战:线程(threading)VS进程(multiprocessing),谁才是并发之王?
【7月更文挑战第10天】Python并发对比:线程轻量级,适合I/O密集型任务,但受GIL限制;进程绕过GIL,擅CPU密集型,但通信成本高。选择取决于应用场景,线程利于数据共享,进程利于多核利用。并发无“王者”,灵活运用方为上策。
|
2天前
|
网络协议 安全 Python
我们将使用Python的内置库`http.server`来创建一个简单的Web服务器。虽然这个示例相对简单,但我们可以围绕它展开许多讨论,包括HTTP协议、网络编程、异常处理、多线程等。
我们将使用Python的内置库`http.server`来创建一个简单的Web服务器。虽然这个示例相对简单,但我们可以围绕它展开许多讨论,包括HTTP协议、网络编程、异常处理、多线程等。
5 0
|
5天前
|
设计模式 缓存 安全
Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
7 0
|
5天前
|
数据采集 数据库连接 调度
从菜鸟到大师:掌握Python asyncio库,并发编程不再是梦!
【7月更文挑战第10天】Python的asyncio库简化了异步编程,通过事件循环和协程实现非阻塞I/O,提升效率。从`async def`定义异步函数到`await`等待操作,如在`main`函数中并发调用`say_hello`。深入学习涉及自定义协程、异步上下文管理器和信号量。结合如aiohttp,能构建高性能并发应用,实现高效的Web服务。开始你的asyncio之旅,成为并发编程专家!**
11 0
|
5天前
|
Python Windows
从菜鸟到大神:一篇文章带你彻底搞懂Python并发编程——线程篇与进程篇的深度较量!
【7月更文挑战第10天】Python并发编程对比线程与进程。线程适合IO密集型任务,利用`threading`模块,但GIL限制CPU并行。进程适用于CPU密集型任务,通过`multiprocessing`实现,独立内存空间,启动成本高。例子展示了如何创建和管理线程与进程以提高效率。选择取决于任务类型和资源需求。
14 0
|
2月前
|
安全 Python
Python中的并发编程:多线程与多进程技术探究
本文将深入探讨Python中的并发编程技术,重点介绍多线程和多进程两种并发处理方式的原理、应用场景及优缺点,并结合实例分析如何在Python中实现并发编程,以提高程序的性能和效率。

相关实验场景

更多