一 、基本概念

以下概念都是在 Python 环境下

  1. Sync 同步编程
  2. Async 异步 ,是指在外观上看来程序不会等待,而是找出可执行的操作/任务/线程 继续执行
  3. Asyncio 单个主线程 多个不同的任务 task ,这些 future 对象 被 event loop 对象控制,就好像多线程版本的多个线程
  4. GIL 全局解释器锁 Global Interpret Lock
  5. Task 任务
  6. 并发 Concurrency 同一时刻只有一个任务/线程 在执行,只不过会不停的切换这些任务
  7. 并行 Parallelism 多个进程同一个时刻一起执行

二、用法

  • Asyncio
import asyncio
import aiohttp
import timeasync def download_one(url):async with aiohttp.ClientSession() as session:async with session.get(url) as resp:save respasync def download_all(sites):tasks = [asyncio.create_task(download_one(site)) for site in sites]await asyncio.gather(*tasks)def main():sites = [......       ]asyncio.run(download_all(sites))if __name__ == '__main__':main()
  • Futures 多线程 线程池执行
   with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:executor.map(download_one, sites)
  • Futures 多进程执行
   with concurrent.futures.ProcessPoolExecutor(max_workers=int(max_workers)) as executor:results = executor.map(open_rebuild_url, df.tolist())

GIL

说到 GIL,首先要明确,GILPython 中 的一个全局解释锁,是 Python 设计解释器 Cpython 的一个技术术语,用于在解释器执行Python 线程时,锁住当前运行的线程,防止其他线程执行。在这个基础上, 你就明白为什么说,Python 是单线程的语言了,因为在GIL 的限制下,只能同时执行一个线程,所谓的多线程实际上是,线程获取和释放 GIL 的切换过程,看起来像 多线程 。

GIL最初,是因为Python的解释器是 Cpython ,GIL 的目的是:

  1. 内存管理的 race condition 资源竞争 ,数据混乱,线程安全的问题
  2. C语言库大部分不是原生线程安全

Python 中 对 GIL 的 释放和获取是 通过 Cpython 解释器的check_interval ,Cpython 会轮询GIL 的状态,每隔一段时间,就会强制释放当前线程锁住的GIL ,给与别的线程执行的机会。

早期的轮询机制是

  1. 100 ticks = 1000bytecodes
  2. Python3 + interval 是 15 ms 轮询一次

Cpython 在 Py3 + 之后,15ms 线程强制释放GIL ,这样对CPU密集型更加的友好,比之前的 bytecodes 要避免很多的切换次数了,但是同一时间仍然只能执行一个线程,所以依旧很慢,多核的多进程,会有CPU0 释放 GIL ,CPU 1,2,3 ,0 竞争线程资源的问题,所以实际上造成了新的问题,线程颠簸 thrashing ,导致效率更低。

所以,多核CPU ,要想快,还是要用 多进程执行 优于 多线程 。这样的意义在于,每个进程都有独立的GIL ,不会发生线程切换的干扰和竞争,实现真正的并行。

那么如果避免 GIL 带来的线程切换的瓶颈呢?

  1. 例如 数据分析 常用库 numpy 的 矩阵运算,是由C实现的Python 库 ,所以不需要cpython 解释器,自然不受 GIL的影响

  2. 绕过Cpython 比如用其他Jpython 等其他实现 ,即,在 Java 代码中执行 Python 代码的方法 ,或者核心(在线程切换造成瓶颈的代码)用C++ 实现按,比如机器学习,AI,人脸识别 等工作的核心代码,基本都是用C++辅助实现的 。

靠脚本语言,去解决CPU密集问题,本身就是一个不切实际的想法,python和c 30倍的性能差距 摆在那里。在实际的工作中,非理论的现实中,很少有靠脚本语言去解决 cpu 密集操作的,而io 密集的高阻塞操作的解决方案,已经有很多了,比如 futures io wait asyncio

Python中的GIL和异步Asyncio、Futures相关推荐

  1. Python中的GIL和深浅拷贝

    Python中的GIL和深浅拷贝 文章目录 Python中的GIL和深浅拷贝 一.GIL全局解释器锁 1.引入 2.GIL 3.Python GIL底层实现原理 4.计算密集型和IO密集型 5.解决G ...

  2. Python中的GIL锁

    Python中的GIL锁 在Python中,可以通过多进程.多线程和多协程来实现多任务. 在多线程的实现过程中,为了避免出现资源竞争问题,可以使用互斥锁来使线程同步(按顺序)执行. 但是,其实Pyth ...

  3. python中对GIL的理解

    深入理解Python中的GIL(全局解释器锁) 1. GIL是什么? 首先来看看GIL究竟是什么.我们需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所 ...

  4. python gil 解除_详解Python中的GIL(全局解释器锁)详解及解决GIL的几种方案

    先看一道GIL面试题: 描述Python GIL的概念, 以及它对python多线程的影响?编写一个多线程抓取网页的程序,并阐明多线程抓取程序是否可比单线程性能有提升,并解释原因. GIL:又叫全局解 ...

  5. 深入理解Python中的GIL(全局解释器锁)

    前言:本博文主要讲解Python中的GIL(全局解释器锁),本人经过查阅多个资料,摒弃一些较官方的描述,用自己的语言整理并加以补充,如果有描述有误的地方,还望读者在评论区指出,谢谢! 文章目录 一.G ...

  6. 深入理解Python中的GIL(全局解释器锁)。

    Python是门古老的语言,要想了解这门语言的多线程和多进程以及协程,以及明白什么时候应该用多线程,什么时候应该使用多进程或协程,我们不得不谈到的一个东西是Python中的GIL(全局解释器锁).这篇 ...

  7. python中的GIL详解

    python中的GIL详解 参考Python-- GIL 锁简述 GIL是什么 首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念.就 ...

  8. 彻底弄懂Python中的GIL锁

    彻底弄懂Python中的GIL锁 转载:https://blog.csdn.net/yushuaigee/article/details/86537474 刚学习python时,我关注了许多介绍pyt ...

  9. 它号称 Python 中性能最高的异步 Web 框架:超详细 Sanic 入门指南!

    △点击上方"Python猫"关注 ,回复"2"加入交流群 作者:古明地盆 来源:https://www.cnblogs.com/traditional/p/14 ...

最新文章

  1. mysql5.6更改datadir数据存储目录
  2. FPGA 之 VGA的IP核编写
  3. 台式电脑怎么连接手机热点_电脑搜不到手机热点 为什么搜不到手机热点
  4. 会签 数据库表设计_关于数据库表设计和实体类设计的思考
  5. 谷歌 colab_如何在Google Colab上使用熊猫分析
  6. mysql集群重启报错lock_CentOS7.2 下 MySQL 之 PXC 集群部署【Docker+单机多节点】
  7. aix系统升级失败提示java_AIX系统补丁升级失败处理
  8. MySQL2种多实例部署方式总结
  9. IBM Rational总经理夏然谈程序员生涯
  10. asp.net 子域跨域 带cookie
  11. 今天的几个财务词汇--待查
  12. [21] Mesh法线的生成算法
  13. 规划资源管理常用表格
  14. GD32 USB调试、DFU过程问题
  15. gcc cross compiler 问题
  16. MATLAB将数据存在TXT文件中
  17. 设计模式之禅【代理模式】
  18. Terracotta学习文档
  19. matlab语言帮助系统题目,西电 matlab语言考试题2009年
  20. java校验商品价格的正则表达式

热门文章

  1. Android am和pm命令
  2. (C语言)求矩阵各行元素之和
  3. matlab不动点迭代代码
  4. 解决UglifyJs Unexpected token punc «{», expected pun 报错问题
  5. SQL注入堆叠注入二次注入
  6. 【C语言入门小游戏】三子棋
  7. 39岁阿里P9失业了,总资产1.5亿,真相是什么?
  8. Java笔记整理(基础)
  9. 头对风,暖烘烘;脚对风,请郎中
  10. 自己设计一个图片加载框架