zoukankan      html  css  js  c++  java
  • Python如何规避全局解释器锁(GIL)带来的限制

    编程语言分类概念介绍(编译型语言、解释型语言、静态类型语言、动态类型语言概念与区别)

    https://www.cnblogs.com/zhoug2020/p/5972262.html

    Python解释器

    一般使用的Python解释器CPython:是用C语言实现Pyhon,是目前应用最广泛的解释器。最新的语言特性都是在这个上面先实现,基本包含了所有第三方库支持,但是CPython有几个缺陷,一是全局锁使Python在多线程效能上表现不佳,二是CPython无法支持JIT(Just-in-time compliation即时编译),导致其执行速度不及Java和Javascipt等语言。于是出现了Pypy。

    Pypy:是用Python自身实现的解释器。针对CPython的缺点进行了各方面的改良,性能得到很大的提升。最重要的一点就是Pypy集成了JIT。但是,Pypy无法支持官方的C/Python API,导致无法使用例如Numpy,Scipy等重要的第三方库。(还有JPython,IronPython等)

    全局解释器锁

    全局解释器锁(Global Interpreter Lock)是Python用于同步线程的工具,使得任何时刻仅有一个线程在执行。 

    Python GIL被动释放机制(抢占机制)

    如果一个线程不间断地在 Python 2 中运行100次解释器的计步(ticks)(可以通过sys.setcheckinterval()设置计步长度),或者不间断地在 Python 3 运行15 毫秒,那么它便会放弃 GIL,而其他线程可以运行。

    全局解释器锁带来的问题

    多线程Python程序无法充分利用多个CPU核心带来的优势。

    (主要影响CPU密集型程序,I/O密集型程序使用多线程一般是明智的选择)

    解决方法

    1,使用多进程

    原理:每个进程分配不同的解释器,有单独的GIL。

    缺点:额外产生数据序列化与通信的开销。

    注意点:待执行操作需包含在以def语句定义的Python函数中(即,在这里lambda,闭包,可调用实例都是不可以的),而且函数参数和返回值必须兼容pickle编码。

    使用方法:廖雪峰Python教程-多进程部分

    2,使用C语言扩展模块

    原理:C语言扩展程序的执行保持与Python解释器隔离,在C代码中释放GIL。

    缺点:调用C函数时GIL会被锁定,若阻塞,解释器无法释放GIL。

    注意点:确保C代码可以独立于Python执行。(不使用Python的数据结构,也不调用Python的C语言API)

    使用方法:在C代码中插入特殊的宏或是使用其他工具来访问C代码,如ctypes库或者Cython。(ctypes默认会在调用C代码时自动释放GIL)

    使用ctypes访问C代码教程

    3,选用其他没有GIL的解释器代替CPython

    原理:使用没有GIL的解释器实现。

    缺点:不完全兼容。

    使用方法:目前Jython和IronPython没有GIL。

    Jython文档IronPython官网

  • 相关阅读:
    JS站点
    1011 World Cup Betting (20分)
    1007 Maximum Subsequence Sum (25分)(动态规划DP)
    1006 Sign In and Sign Out (25分)
    1005 Spell It Right (20分)
    1004 Counting Leaves (30分)(DFS)
    1003 Emergency (25分)(Dijkstra算法)
    1002 A+B for Polynomials (25分)
    1001 A+B Format (20分)
    canvas
  • 原文地址:https://www.cnblogs.com/weswes/p/9987986.html
Copyright © 2011-2022 走看看