Python中的GIL和异步Asyncio、Futures
一 、基本概念
以下概念都是在 Python 环境下
Sync
同步编程Async
异步 ,是指在外观上看来程序不会等待,而是找出可执行的操作/任务/线程 继续执行Asyncio
单个主线程 多个不同的任务task
,这些future
对象 被event loop
对象控制,就好像多线程版本的多个线程GIL
全局解释器锁Global Interpret Lock
Task
任务- 并发
Concurrency
同一时刻只有一个任务/线程 在执行,只不过会不停的切换这些任务 - 并行
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
,首先要明确,GIL
是 Python
中 的一个全局解释锁,是 Python
设计解释器 Cpython
的一个技术术语,用于在解释器执行Python 线程时,锁住当前运行的线程,防止其他线程执行。在这个基础上, 你就明白为什么说,Python 是单线程
的语言了,因为在GIL 的限制下,只能同时执行一个线程,所谓的多线程实际上是,线程获取和释放 GIL 的切换过程,看起来像 多线程 。
GIL最初,是因为Python的解释器是 Cpython ,GIL 的目的是:
- 内存管理的
race condition
资源竞争 ,数据混乱,线程安全的问题 - C语言库大部分不是
原生线程安全
的
Python 中 对 GIL 的 释放和获取
是 通过 Cpython 解释器的check_interval
,Cpython 会轮询GIL 的状态,每隔一段时间,就会强制释放当前线程锁住的GIL ,给与别的线程执行的机会。
早期的轮询机制是
- 100 ticks = 1000bytecodes
- Python3 + interval 是 15 ms 轮询一次
Cpython 在 Py3 + 之后,15ms 线程强制释放GIL ,这样对CPU密集型更加的友好,比之前的 bytecodes 要避免很多的切换次数了,但是同一时间仍然只能执行一个线程,所以依旧很慢,多核的多进程,会有CPU0 释放 GIL ,CPU 1,2,3 ,0 竞争线程资源的问题,所以实际上造成了新的问题,线程颠簸 thrashing ,导致效率更低。
所以,多核CPU ,要想快,还是要用 多进程执行 优于 多线程 。这样的意义在于,每个进程都有独立的GIL ,不会发生线程切换的干扰和竞争,实现真正的并行。
那么如果避免 GIL 带来的线程切换的瓶颈呢?
例如 数据分析 常用库 numpy 的 矩阵运算,是由C实现的Python 库 ,所以不需要cpython 解释器,自然不受 GIL的影响
绕过Cpython 比如用其他Jpython 等其他实现 ,即,在 Java 代码中执行 Python 代码的方法 ,或者核心(在线程切换造成瓶颈的代码)用C++ 实现按,比如机器学习,AI,人脸识别 等工作的核心代码,基本都是用C++辅助实现的 。
靠脚本语言,去解决CPU密集问题,本身就是一个不切实际的想法,python和c 30倍的性能差距 摆在那里。在实际的工作中,非理论的现实中,很少有靠脚本语言去解决 cpu 密集操作的,而io 密集的高阻塞操作的解决方案,已经有很多了,比如 futures io wait asyncio
Python中的GIL和异步Asyncio、Futures相关推荐
- Python中的GIL和深浅拷贝
Python中的GIL和深浅拷贝 文章目录 Python中的GIL和深浅拷贝 一.GIL全局解释器锁 1.引入 2.GIL 3.Python GIL底层实现原理 4.计算密集型和IO密集型 5.解决G ...
- Python中的GIL锁
Python中的GIL锁 在Python中,可以通过多进程.多线程和多协程来实现多任务. 在多线程的实现过程中,为了避免出现资源竞争问题,可以使用互斥锁来使线程同步(按顺序)执行. 但是,其实Pyth ...
- python中对GIL的理解
深入理解Python中的GIL(全局解释器锁) 1. GIL是什么? 首先来看看GIL究竟是什么.我们需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所 ...
- python gil 解除_详解Python中的GIL(全局解释器锁)详解及解决GIL的几种方案
先看一道GIL面试题: 描述Python GIL的概念, 以及它对python多线程的影响?编写一个多线程抓取网页的程序,并阐明多线程抓取程序是否可比单线程性能有提升,并解释原因. GIL:又叫全局解 ...
- 深入理解Python中的GIL(全局解释器锁)
前言:本博文主要讲解Python中的GIL(全局解释器锁),本人经过查阅多个资料,摒弃一些较官方的描述,用自己的语言整理并加以补充,如果有描述有误的地方,还望读者在评论区指出,谢谢! 文章目录 一.G ...
- 深入理解Python中的GIL(全局解释器锁)。
Python是门古老的语言,要想了解这门语言的多线程和多进程以及协程,以及明白什么时候应该用多线程,什么时候应该使用多进程或协程,我们不得不谈到的一个东西是Python中的GIL(全局解释器锁).这篇 ...
- python中的GIL详解
python中的GIL详解 参考Python-- GIL 锁简述 GIL是什么 首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念.就 ...
- 彻底弄懂Python中的GIL锁
彻底弄懂Python中的GIL锁 转载:https://blog.csdn.net/yushuaigee/article/details/86537474 刚学习python时,我关注了许多介绍pyt ...
- 它号称 Python 中性能最高的异步 Web 框架:超详细 Sanic 入门指南!
△点击上方"Python猫"关注 ,回复"2"加入交流群 作者:古明地盆 来源:https://www.cnblogs.com/traditional/p/14 ...
最新文章
- mysql5.6更改datadir数据存储目录
- FPGA 之 VGA的IP核编写
- 台式电脑怎么连接手机热点_电脑搜不到手机热点 为什么搜不到手机热点
- 会签 数据库表设计_关于数据库表设计和实体类设计的思考
- 谷歌 colab_如何在Google Colab上使用熊猫分析
- mysql集群重启报错lock_CentOS7.2 下 MySQL 之 PXC 集群部署【Docker+单机多节点】
- aix系统升级失败提示java_AIX系统补丁升级失败处理
- MySQL2种多实例部署方式总结
- IBM Rational总经理夏然谈程序员生涯
- asp.net 子域跨域 带cookie
- 今天的几个财务词汇--待查
- [21] Mesh法线的生成算法
- 规划资源管理常用表格
- GD32 USB调试、DFU过程问题
- gcc cross compiler 问题
- MATLAB将数据存在TXT文件中
- 设计模式之禅【代理模式】
- Terracotta学习文档
- matlab语言帮助系统题目,西电 matlab语言考试题2009年
- java校验商品价格的正则表达式