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官网

  • 相关阅读:
    设计模式(15)-命令模式
    设计模式(14)-模板方法模式
    设计模式(13)-代理模式
    设计模式(12)-享元模式
    设计模式(3)-工厂方法模式
    微服务(1)-简单初始化项目
    MCMC:Markov Chain&Monte Carlo(二)MH采样和Gibbs采样,MCMC局限性
    MCMC:Markov Chain& Monte Carlo(一)基本cdf采样,rejection采样,Importance采样
    指数族分布:相关概念理解
    matlab隐马尔可夫相关函数简单例子实现(help文档)
  • 原文地址:https://www.cnblogs.com/weswes/p/9987986.html
Copyright © 2011-2022 走看看