Python GIL 的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
jenrey
V2EX    Python

Python GIL 的问题

  •  
  •   jenrey 2023-09-03 23:04:54 +08:00 2682 次点击
    这是一个创建于 797 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    16 条回复    2023-09-27 11:35:42 +08:00
    F281M6Dh8DXpD1g2
        1
    F281M6Dh8DXpD1g2  
       2023-09-03 23:05:52 +08:00
    你的意思是单核 cpu 就不能有多线程了?
    iseki
        2
    iseki  
       2023-09-03 23:07:39 +08:00
    原始链接呢,原文呢,按理说不该有这样的问题
    jenrey
        3
    jenrey  
    OP
       2023-09-03 23:26:48 +08:00
    @liprais 我感觉图中的意思,只是想表达 Python GIL 在单核 CPU 下进行多线程并发,仍需要给 obj 对象加锁。
    而 Python GIL 的诞生 只是为了解决 在多核 CPU 下执行多线程“并行”任务时 Python 的引用计数器不是线程安全 的问题。也就是说 Python GIL 的出现让多核 CPU 下执行多线程 并发 任务时引用计数器是线程安全的。
    所以,这个图配得不好,应该加个标题《即使有 Python GIL ,我们仍需给共享对象加锁,无论 CPU 核心数》。
    不知道我理解的对不对。
    wevsty     4
    wevsty  
       2023-09-03 23:47:13 +08:00
    单核时代一样可以多进程,多线程。
    线程的调度是由 OS 来决定的,跟你有几个 CPU 核心没有必然的关系。
    lovelylain
        5
    lovelylain  
       2023-09-04 00:11:34 +08:00 via Android
    @jenrey 写过多线程程序没?多线程环境下操作同一个对象,为了避免线程安全问题,最常见的方案就是加锁,Python GIL 同理,如果编译为不支持多线程,是不需要 GIL 的,但支持多线程后,为了避免引用技等出现
    lovelylain
        6
    lovelylain  
       2023-09-04 00:14:49 +08:00 via Android
    @jenrey 写过多线程程序没?多线程环境下操作同一个对象,为了避免线程安全问题,最常见的方案就是加锁,Python GIL 同理,如果编译为不支持多线程,是不需要 GIL 的,但支持多线程后,为了避免引用计数等出现线程安全问题,就引入了 GIL ,单核 CPU 也可以多线程
    也存在线程安全问题的。
    jackOff
        7
    jackOff  
       2023-09-04 01:48:25 +08:00 via Android
    Python 全局解释器导致了多线程大多数情况就是个笑话,仅仅在网络通信和读写文件上能稍微体现一点。其他方面使用它还不如使用异步编程,当然多进程可以改善这种情况,但是这就是使代码开发变得极度简单化的一个代价
    mylifcc
        8
    mylifcc  
       2023-09-04 02:02:11 +08:00
    GIL 是解释器级别的锁,可以保证同一时间只有 1 个线程在 CPU 运行来改这个参数,如果用 GO 就可能会有多个线程在同时改了,这样说你懂了吧。。。这个问题属于业务级别的问题,归根结底是设计问题,你允不允许非同一时间的线程来改一个值的,如果允许,就不需要加锁,因为你业务就是这么设计的。
    ysc3839
        9
    ysc3839  
       2023-09-04 02:59:59 +08:00 via Android
    不会出现图中的问题,加锁之后需要持有锁的线程主动解锁,此时如果切换到了线程 B ,线程 B 没法锁定,就只能等待。
    est
        10
    est  
       2023-09-04 09:07:18 +08:00
    你说下这图谁画的吧。我让作者出来给你解释。
    itskingname
        11
    itskingname  
       2023-09-04 09:55:46 +08:00
    我以前写过一篇文章来说明这个问题: https://mp.weixin.qq.com/s/a37OxUjgHdps1ZsPB7pKcQ
    sujin190
        12
    sujin190  
       2023-09-04 10:35:31 +08:00   1
    GIL 限制的是单个字节码级别的原子操作不能并发,就算是简单 a+=1 这样的也是需要多条字节码指令的,所以也不能保证是原子操作,并不是你想的那种给对象加锁,你可以用 dis 模块研究下代码和编译生成的字节码对应关系
    jenrey
        13
    jenrey  
    OP
       2023-09-04 13:19:30 +08:00
    @ysc3839 所以我感觉原图和 GIL 锁的原理没啥关系,只是表明 Python 有了 GIL 后,在多线程下是并发执行的,而非并行执行,与 CPU 的核心数也无关系,只会采用单核心时间片调度多个线程,所以只是个提醒图(提醒如果不给共享对象加锁,会出问题而已)
    引用计数器的方案有瑕疵,即 当两个线程同时提高同一个对象的引用计数时,(如果没有 GIL 锁)那么引用计数只会被提高了 1 次而不是 2 次。所以 GIL 就诞生了。
    NoAnyLove
        14
    NoAnyLove  
       2023-09-04 16:20:36 +08:00
    不会出现这种问题,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  
       2023-09-06 10:28:46 +08:00
    GIL 不防呆.
    Cu635
        16
    Cu635  
       2023-09-27 11:35:42 +08:00
    链接里面的图是用什么画的?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     943 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 23:06 PVG 07:06 LAX 15:06 JFK 18:06
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86