最近在看 Python 的多线程,经常我们会听到老手说: “python下多线程是鸡肋,推荐使用多进程!” ,但是为什么这么说呢?

要知其然,更要知其所以然。所以有了下面的深入研究:

首先强调背景:

1、GIL是什么?GIL的全称是Global Interpreter Lock(全局解释器锁),来源是python设计之初的考虑,为了数据安全所做的决定。

2、每个CPU在同一时间只能执行一个线程(在单核CPU下的多线程其实都只是并发,不是并行,并发和并行从宏观上来讲都是同时处理多路请求的概念。但并发和并行又有区别,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。)

在Python多线程下,每个线程的执行方式:
1.获取GIL
2.执行代码直到sleep或者是python虚拟机将其挂起。
3.释放GIL

可见,某个线程想要执行,必须先拿到GIL,我们可以把GIL看作是“通行证”,并且在一个python进程中,GIL只有一个。拿不到通行证的线程,就不允许进入CPU执行。

在python2.x里,GIL的释放逻辑是当前线程遇见IO操作或者ticks计数达到100(ticks可以看作是python自身的一个计数器,专门做用于GIL,每次释放后归零,这个计数可以通过 sys.setcheckinterval 来调整),进行释放。

而每次释放GIL锁,线程进行锁竞争、切换线程,会消耗资源。并且由于GIL锁存在,python里一个进程永远只能同时执行一个线程(拿到GIL的线程才能执行),这就是为什么在多核CPU上,python的多线程效率并不高。

那么是不是python的多线程就完全没用了呢?

在这里我们进行分类讨论:

1、CPU密集型代码(各种循环处理、计数等等),在这种情况下,ticks计数很快就会达到阈值,然后触发GIL的释放与再竞争(多个线程来回切换当然是需要消耗资源的),所以python下的多线程对CPU密集型代码并不友好。

2、IO密集型代码(文件处理、网络爬虫等),多线程能够有效提升效率(单线程下有IO操作会进行IO等待,造成不必要的时间浪费,而开启多线程能在线程A等待时,自动切换到线程B,可以不浪费CPU的资源,从而能提升程序执行效率)。所以python的多线程对IO密集型代码比较友好。

而在python3.x中,GIL不使用ticks计数,改为使用计时器(执行时间达到阈值后,当前线程释放GIL),这样对CPU密集型程序更加友好,但依然没有解决GIL导致的同一时间只能执行一个线程的问题,所以效率依然不尽如人意。

多核多线程比单核多线程更差,原因是单核下多线程,每次释放GIL,唤醒的那个线程都能获取到GIL锁,所以能够无缝执行,但多核下,CPU0释放GIL后,其他CPU上的线程都会进行竞争,但GIL可能会马上又被CPU0拿到,导致其他几个CPU上被唤醒后的线程会醒着等待到切换时间后又进入待调度状态,这样会造成线程颠簸(thrashing),导致效率更低

回到最开始的问题:经常我们会听到老手说:“python下想要充分利用多核CPU,就用多进程”,原因是什么呢?

原因是:每个进程有各自独立的GIL,互不干扰,这样就可以真正意义上的并行执行,所以在python中,多进程的执行效率优于多线程(仅仅针对多核CPU而言)。

所以我们能够得出结论:多核下,想做并行提升效率,比较通用的方法是使用多进程,能够有效提高执行效率

Python GIL锁相关推荐

  1. Python GIL 锁 - Python零基础入门教程

    目录 一.并行和并发 二.GIL 锁 案例一:单核多线程 案例二:单核多线程 案例三:双核多线程 三.如何解决 GIL 锁问题 四.猜你喜欢 零基础 Python 学习路线推荐 : Python 学习 ...

  2. python gil锁_python中的GIL锁

    熟悉python的都知道,在C语言写的python解释器中存在全局解释器锁,由于全局解释器锁的存在,在同一时间内,python解释器只能运行一个线程的代码,这大大影响了python多线程的性能.而这个 ...

  3. python gil锁存在的意义_关于python的GIL全局解释器锁的简单理解

    GIL是解释器内部的一把锁,确切一点说是CPython解释器内部的一把锁,所以要注意区分 这和我们在Python代码中使用线程锁Lock并不是一个层面的概念. 1. GIL产生的背景: 在CPytho ...

  4. python 对象锁_也许你对 Python GIL 锁的理解是 错的。

    摄影:产品经理甜白与草莓更配~ 我刚到现在这个公司时,听到当时一个高级工程师(现已离职)大声地跟他旁边的同事说:  Python 有 GIL 锁,所以它的多线程实际上是单线程,所以写多线程代码不用考 ...

  5. python gil锁为什么_day9-为什么会有GIL锁 (来自师兄总结的博客)

    一.前言 我的机器有4核,代表着同一时间,可以干4个任务.如果单核cpu的话,我启动10个线程,我看上去也是并发的,因为是执行了上下文的切换,让我看上去是并发的.但是单核永远肯定时串行的,它肯定是串行 ...

  6. python gil锁存在的意义_对于Python的GIL锁理解

    GIL是什么 首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念.就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可 ...

  7. Python GIL锁问题探究及解决

    1. 什么是GIL? GIL即全局解释器(global interpreter lock).python的每个线程在执行时都需要先获取GIL,保证同一时刻只有一个线程可以执行代码,即同一时刻只有持有G ...

  8. python GIL锁,如何解决

    GIL锁: 全局解释器锁,是由于Cpython解释器自带的:在Cpython解释器中运行的多线程,每个线程在执行的时候,都会先获取一个GIL锁,保证同一时刻只有一个线程可以执行: 线程释放GIL锁的情 ...

  9. python gil锁_python GIL锁问题

    一.GIL是什么 官方解释: In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple na ...

最新文章

  1. SB Admin 2 学习笔记1
  2. 双字节数据 先低后高_1.4 C++数据类型
  3. windows ping 不通虚拟机
  4. js通过身份证获取年龄
  5. reading notes -- Amazon.com Recommendations: Item-to-Item Collaborative Filtering
  6. 【csust】寻宝(贪心,思维)
  7. ios7自定义返回按钮后,右滑返回功能失效解决方法
  8. Http状态行和状态码介绍
  9. 如何查看别人的微信公众号的粉丝数
  10. PTA 背包问题凑零钱
  11. Webpack文件指纹
  12. Error relaunching VirtualBox VM process:5错误解决
  13. 2021 MCU WiFi竞争新格局,国产MCU WiFi芯片盘点,附录2020/2021 MCU WiFi排行
  14. NPL系列之分词和分词框架(二)
  15. Java面试题基础系列228道(2),查漏补缺
  16. android UVCCamera could not negotiate with camera:err=-51
  17. JavaScript 常用实例
  18. BDD之单元测试(三):BDD的官方教程
  19. javancss中的NCSS和CCN
  20. 微信小程序-开发实战(二)

热门文章

  1. kafka客户端--wakeup方法
  2. 合成复用原则(Composite Reuse Principle)
  3. 计数排序C++(考虑周全版本)
  4. 程序员高薪晋升必备的40个小技巧
  5. 深夜里,程序员最喜欢去的网站竟然是......
  6. JAVA计算机毕业设计新锐台球厅管理系统计算机(附源码、数据库)
  7. sysctl 默认值_Linux中的Sysctl命令
  8. ipad手写笔推荐品牌,推荐性价比最高的平替苹果笔
  9. Python将DOCX转换为markdown文件
  10. 未能加载基类的解决方案