• 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占用率一般不高
        # 使用 线程/协程
  • 相关阅读:
    生手和FinallyJane一起学习ASP.NET
    使用eclipse 初学java
    关于C#中用access做数据库,使用like语句的问题(转)
    VSS (Visual Source Safe 2005) 用法详解(转)
    mysql 字符集问题之我见
    mysqli的预处理功能使用
    兼容IE和Firefox
    linux下netsnmp 已经安装,为什么没有 snmpwalk和snmpget
    ? PHP WBEM
    安装cacti时提示错误
  • 原文地址:https://www.cnblogs.com/believepd/p/10409792.html
Copyright © 2020-2023  润新知