zoukankan      html  css  js  c++  java
  • GIL(全局解释器锁)

    1、GIL:全局解释器锁。每个线程在执行的过程都需要先获取GIL,保证同一时刻只有一个线程可以执行代码。

    2、Python和GIL没有半毛钱关系,它是在实现CPython解析器时所引入的一个概念。因为CPython解释器是大部分环境下默认的Python执行环境。由于历史原因,现在非常难以移除。

    3、线程释放GIL锁的情况:在IO操作等可能会引起阻塞的 system call 之前,可以暂时释放GIL,但在执行完毕后,必须重新获取GIL。

    4、Python使用多进程是可以利用多核的CPU资源的。

    5、爬虫:多线程爬取比单线程爬取,性能有所提升,因为遇到IO阻塞会自动释放GIL锁。

    一、测试

    在虚拟机中启动linux系统,使用htop命令可看到如下图所示。图中的1、2表示我给当前cpu设置为双核;双核指:同一时刻可以做两件事,且这两件事是互相独立的。

    测试代码

    01-单线程死循环.py

    # 主线程死循环,占满cpu
    while True:
        pass

    情况1:一个终端运行这份代码。

    结果1:运行代码,可以看到单线程任务占满了一个核;结束运行,这个核的占用率立马就降下来了。

    情况2:一个终端运行这份代码,在另一个终端再次运行这份代码。

    结果2:这两个线程分别占满了这两个核。

    02-2个线程死循环.py

    import threading
    
    # 子线程死循环
    def task():
        while True:
            pass
    
    t = threading.Thread(target=task)
    t.start()
    
    # 主线程死循环
    while True:
        pass

    现象:这两个核的使用率大致都为50%,它们加起来才算真正一个核的资源率。

    推测:如果你的程序是多线程,实际上是假的多任务。验证如下:

    03-2个进程死循环.py

    import multiprocessing
    
    def task():
        while True:
            pass

    # 子进程死循环 p = multiprocessing.Process(target=task) p.start() # 主进程死循环 while True: pass

    验证得知:在完成一件事情,如果用了多进程、多线程、多协程的这种情况下,真正实现多并发效果的是多进程,多线程可以说是"假"的多并发。为什么这么说呢?因为Cpython解释器的GIL,进程是没有GIL的,线程才有。也就是说,GIL导致程序:你看上去像多并发,实际上是一个在干活,另一个在休息,另一个在干活时,这个又休息了,即只有一个线程在运行。

    二、总结

    # 计算密集型
        程序系统,大部分时间是CPU在做计算、逻辑判断等,导致cpu占用率很高,而I/O在很短的时间就可以完成
        # 使用 多进程
    # I/O密集型
        程序系统,大部分时间是CPU在等I/O,如:频繁网络传输、硬盘/内存读写;I/O密集型的cpu占用率一般不高
        # 使用 线程/协程
  • 相关阅读:
    【官网翻译】性能篇(四)为电池寿命做优化——使用Battery Historian分析电源使用情况
    【官网翻译】性能篇(三)为电池寿命做优化——概述
    【官网翻译】性能篇(二)通过线程提高性能
    Mybatis+Struts2的结合:实现用户插入和查找
    在安装mysql出现的错误以及解决方法
    关于PHP的内置服务器的使用
    误用.Net Redis客户端CSRedisCore,自己挖坑自己填
    dotnet代码管理之密钥分离策略
    dotnetcore三大Redis客户端对比和使用心得
    生产环境(基于docker)故障排除? 有感于博客园三番五次翻车
  • 原文地址:https://www.cnblogs.com/believepd/p/10409792.html
Copyright © 2011-2022 走看看