Python 核心技术与实战
景霄
Facebook 资深工程师
114324 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 47 讲
开篇词 (1讲)
Python 核心技术与实战
15
15
1.0x
00:00/00:00
登录|注册

21 | Python并发编程之Futures

I/O操作时释放锁,让其他线程继续执行
引入全局解释器锁,同一时刻只允许一个线程执行
Python解释器不是线程安全的
as_completed(fs)返回完成后的迭代器
result()返回操作结果或异常
add_done_callback(fn)在操作完成后执行回调函数
done()表示操作是否完成
executor.submit(func)安排函数执行并返回future实例
结果或异常在操作完成后获取
状态随时可以查询
将处于等待状态的操作包裹起来放到队列中
带有延迟的操作
线程数需根据实际需求测试找到最优数量
使用ThreadPoolExecutor提高效率
大部分时间浪费在I/O等待上
效率低下
适用于CPU heavy的场景
多个进程同时执行
适用于I/O操作频繁的场景
同一时刻只允许一个线程/任务执行
线程/任务之间互相切换
全局解释器锁的影响
Futures的原理和常用函数
多线程版本的性能优势
并发和并行的概念与区别
全局解释器锁
Executor类
Futures模块
多线程
单线程
并行
并发
总结
为什么多线程每次只能有一个线程执行?
到底什么是Futures?
单线程与多线程性能比较
区分并发和并行
Python并发编程之Futures

该思维导图由 AI 生成,仅供参考

你好,我是景霄。
无论对于哪门语言,并发编程都是一项很常用很重要的技巧。比如我们上节课所讲的很常见的爬虫,就被广泛应用在工业界的各个领域。我们每天在各个网站、各个 App 上获取的新闻信息,很大一部分便是通过并发编程版的爬虫获得。
正确合理地使用并发编程,无疑会给我们的程序带来极大的性能提升。今天这节课,我就带你一起来学习理解、运用 Python 中的并发编程——Futures。

区分并发和并行

在我们学习并发编程时,常常同时听到并发(Concurrency)和并行(Parallelism)这两个术语,这两者经常一起使用,导致很多人以为它们是一个意思,其实不然。
首先你要辨别一个误区,在 Python 中,并发并不是指同一时刻有多个操作(thread、task)同时进行。相反,某个特定的时刻,它只允许有一个操作发生,只不过线程 / 任务之间会互相切换,直到完成。我们来看下面这张图:
图中出现了 thread 和 task 两种切换顺序的不同方式,分别对应 Python 中并发的两种形式——threading 和 asyncio。
对于 threading,操作系统知道每个线程的所有信息,因此它会做主在适当的时候做线程切换。很显然,这样的好处是代码容易书写,因为程序员不需要做任何切换操作的处理;但是切换线程的操作,也有可能出现在一个语句执行的过程中(比如 x += 1),这样就容易出现 race condition 的情况。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Python并发编程中的Futures技术概览 本文介绍了Python中的并发编程技术Futures,通过比较单线程和多线程的性能,展示了Futures的优势。文章通过实例代码演示了如何使用Futures实现多线程下载网站内容,并对比了单线程和多线程的性能差异。此外,还提到了使用多进程的并行方式,强调了多进程并不适用于I/O heavy的操作,而适用于CPU heavy的场景。最后,总结了并行和并发的适用场景,以及如何根据实际需求选择最优的线程或进程数量。通过本文的介绍,读者可以快速了解Python中的并发编程技术Futures,以及如何利用Futures提升程序性能,特别是在I/O操作频繁的场景下。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Python 核心技术与实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(55)

  • 最新
  • 精选
  • KaitoShy
    思考题: 1. request.get 会触发:ConnectionError, TimeOut, HTTPError等,所有显示抛出的异常都是继承requests.exceptions.RequestException 2. executor.map(download_one, urls) 会触发concurrent.futures.TimeoutError 3. result() 会触发Timeout,CancelledError 4. as_completed() 会触发TimeOutError

    作者回复: 回答的很对

    2019-06-26
    4
    71
  • Goal
    学习到的知识点: 1. 并发和并行的区别,大佬通俗易懂的方式让我更深刻的体会到了程序到底是如何跑在多核机器上的 2. python中 Futures 特性,第一次接触到这个模块,待后续继续加深了解; 3. Python 中之所以同一时刻只允许一个线程运行,大佬解释了这是因为全局解释器锁的存在,而全局解释器锁又是为了解决 race condition而引入的,这个也从另一方面验证了我之前学习到的,python中多线程是无法利用多核的; 但是多线程无法利用多核也并不是一无是处,就像大佬在文中聊到的,多线程主要的适用场景就是 有IO延迟的场景,因为一个线程遇到IO延迟,它占用的全局解释器锁就会释放,而另一个线程即可以拿到锁开始执行; 这种在IO延迟场景中的并发,高效也是显而易见的;

    作者回复: 说的很对

    2020-01-09
    8
  • Steve
    老师,我有一个很类似的场景。之前我用单线程去下载所有页面。然后在每个页面解析出需要的内容放入一个集合里。如果改成并发的实现,多线程写一个集合(写文件也类似),是不是有线程安全的问题。有没有小例子可以学习一下~

    作者回复: 可以用 python 线程安全的容器,例如 Queue. 如果内存存不下,可以用数据库,而不是直接写文件。

    2020-05-15
    7
  • Geek_5bb182
    老师你好,concurrent.futures 和 asyncio 中的Future 的区别是什么,在携程编程中

    作者回复: 可以参考https://stackoverflow.com/questions/29902908/what-is-the-difference-between-concurrent-futures-and-asyncio-futures

    2019-06-27
    7
  • 干布球
    请问老师,future任务是调用submit后就开始执行,还是在调用as_completed之后才开始执行呢?

    作者回复: submit之后

    2019-06-26
    3
    4
  • helloworld
    总结下并发和并行的概念: 并发,是指遇到I/O阻塞时(一般是网络I/O或磁盘I/O),通过多个线程之间切换执行多个任务(多线程)或单线程内多个任务之间切换执行的方式来最大化利用CPU时间,但同一时刻,只允许有一个线程或任务执行。适合I/O阻塞频繁的业务场景。 并行,是指多个进程完全同步同时的执行。适合CPU密集型业务场景。

    作者回复: 没错

    2019-06-26
    3
    3
  • LJK
    老师好,请问一下在python存在GIL的情况下,多进程是不是还是无法并发运行?谢谢老师

    作者回复: 如果是多进程,则无所谓,可以并发运行。GIL是作用在线程上的,是不允许进程中的多线程同时运行

    2019-06-26
    4
    3
  • 简传宝
    老师好,请问是否可以理解为计算密集型任务用多进程,io密集型用多线程

    作者回复: 没错。CPU-bound的任务主要是multi-processing,IO-bound的话,如果IO比较快,用多线程,如果IO比较慢,用asyncio,因为效率更加高

    2019-06-27
    2
  • MarDino
    想问下老师,该怎么向executor.map中的函数,传入多个参数?

    作者回复: 这个map函数的用法可以参照https://docs.python.org/3/library/concurrent.futures.html

    2020-02-11
    1
  • _stuView
    老师,请问什么是线程安全,什么是race condition呢?

    作者回复: 可以参考https://en.wikipedia.org/wiki/Thread_safety

    2019-06-26
    1
收起评论
显示
设置
留言
55
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部