Python GIL 的问题 - V2EX
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
jenrey

Python GIL 的问题

  •  
  •   jenrey Sep 3, 2023 3023 views
    This topic created in 987 days ago, the information mentioned may be changed or developed.

    如下图所示,Python 使用 GIL 也会出现图中这样的问题,那么 GIL 存在的意义是什么?谢谢 https://imgur.com/a/YCoqzm1

    16 replies    2023-09-27 11:35:42 +08:00
    F281M6Dh8DXpD1g2
        1
    F281M6Dh8DXpD1g2  
       Sep 3, 2023
    你的意思是单核 cpu 就不能有多线程了?
    iseki
        2
    iseki  
       Sep 3, 2023
    原始链接呢,原文呢,按理说不该有这样的问题
    jenrey
        3
    jenrey  
    OP
       Sep 3, 2023
    @liprais 我感觉图中的意思,只是想表达 Python GIL 在单核 CPU 下进行多线程并发,仍需要给 obj 对象加锁。
    而 Python GIL 的诞生 只是为了解决 在多核 CPU 下执行多线程“并行”任务时 Python 的引用计数器不是线程安全 的问题。也就是说 Python GIL 的出现让多核 CPU 下执行多线程 并发 任务时引用计数器是线程安全的。
    所以,这个图配得不好,应该加个标题《即使有 Python GIL ,我们仍需给共享对象加锁,无论 CPU 核心数》。
    不知道我理解的对不对。
    wevsty
        4
    wevsty  
       Sep 3, 2023
    单核时代一样可以多进程,多线程。
    线程的调度是由 OS 来决定的,跟你有几个 CPU 核心没有必然的关系。
    lovelylain
        5
    lovelylain  
       Sep 4, 2023 via Android
    @jenrey 写过多线程程序没?多线程环境下操作同一个对象,为了避免线程安全问题,最常见的方案就是加锁,Python GIL 同理,如果编译为不支持多线程,是不需要 GIL 的,但支持多线程后,为了避免引用技等出现
    lovelylain
        6
    lovelylain  
       Sep 4, 2023 via Android
    @jenrey 写过多线程程序没?多线程环境下操作同一个对象,为了避免线程安全问题,最常见的方案就是加锁,Python GIL 同理,如果编译为不支持多线程,是不需要 GIL 的,但支持多线程后,为了避免引用计数等出现线程安全问题,就引入了 GIL ,单核 CPU 也可以多线程
    也存在线程安全问题的。
    jackOff
        7
    jackOff  
       Sep 4, 2023 via Android
    Python 全局解释器导致了多线程大多数情况就是个笑话,仅仅在网络通信和读写文件上能稍微体现一点。其他方面使用它还不如使用异步编程,当然多进程可以改善这种情况,但是这就是使代码开发变得极度简单化的一个代价
    mylifcc
        8
    mylifcc  
       Sep 4, 2023
    GIL 是解释器级别的锁,可以保证同一时间只有 1 个线程在 CPU 运行来改这个参数,如果用 GO 就可能会有多个线程在同时改了,这样说你懂了吧。。。这个问题属于业务级别的问题,归根结底是设计问题,你允不允许非同一时间的线程来改一个值的,如果允许,就不需要加锁,因为你业务就是这么设计的。
    ysc3839
        9
    ysc3839  
       Sep 4, 2023 via Android
    不会出现图中的问题,加锁之后需要持有锁的线程主动解锁,此时如果切换到了线程 B ,线程 B 没法锁定,就只能等待。
    est
        10
    est  
       Sep 4, 2023
    你说下这图谁画的吧。我让作者出来给你解释。
    itskingname
        11
    itskingname  
       Sep 4, 2023
    我以前写过一篇文章来说明这个问题: https://mp.weixin.qq.com/s/a37OxUjgHdps1ZsPB7pKcQ
    sujin190
        12
    sujin190  
       Sep 4, 2023   1
    GIL 限制的是单个字节码级别的原子操作不能并发,就算是简单 a+=1 这样的也是需要多条字节码指令的,所以也不能保证是原子操作,并不是你想的那种给对象加锁,你可以用 dis 模块研究下代码和编译生成的字节码对应关系
    jenrey
        13
    jenrey  
    OP
       Sep 4, 2023
    @ysc3839 所以我感觉原图和 GIL 锁的原理没啥关系,只是表明 Python 有了 GIL 后,在多线程下是并发执行的,而非并行执行,与 CPU 的核心数也无关系,只会采用单核心时间片调度多个线程,所以只是个提醒图(提醒如果不给共享对象加锁,会出问题而已)
    引用计数器的方案有瑕疵,即 当两个线程同时提高同一个对象的引用计数时,(如果没有 GIL 锁)那么引用计数只会被提高了 1 次而不是 2 次。所以 GIL 就诞生了。
    NoAnyLove
        14
    NoAnyLove  
       Sep 4, 2023
    不会出现这种问题,GIL 会保证每条指令的执行是 atomic 的,可以看看 t/965954

    如果主动撤销对某个 obj 的引用,多半是是使用`del obj`语句(也可能是其他语句),也就是一条 DELETE_NAME (或者别的 DELETE 指令)。减少引用和具体的回收工作都在这一条指令中完成了,

    ```
    >>> import dis
    >>> dis.dis("del obj")
    1 0 DELETE_NAME 0 (obj)
    2 LOAD_CONST 0 (None)
    4 RETURN_VALUE
    ```
    akaHenry
        15
    akaHenry  
       Sep 6, 2023
    GIL 不防呆.
    Cu635
        16
    Cu635  
       Sep 27, 2023
    链接里面的图是用什么画的?
    About     Help     Advertise     Blog     API     FAQ     Solana     2977 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 64ms UTC 12:48 PVG 20:48 LAX 05:48 JFK 08:48
    Do have faith in what you're doing.