热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python有GIL为什么还需要线程同步?

Python有GIL保证相关对象的同时操作,那为什么还需要进行线程同步?是不是因为在虚拟机层面之上在多线程工作时还需要提供相关的锁机制、队列机制,这其中的原理是什么?有其他类似的例子吗?还是说Python内部的GIL保证了一个变量的引用数量,但是当多线程使用同一资源时,例如sys.stdout,这个时候是需要线程同步来确保资源访问不冲突,GIL不提供类似资源的保护吗?
Python 有GIL保证相关对象的同时操作,那为什么还需要进行线程同步?是不是因为在虚拟机层面之上在多线程工作时还需要提供相关的锁机制、队列机制,这其中的原理是什么?有其他类似的例子吗? 还是说Python内部的GIL保证了一个变量的引用数量,但是当多线程使用同一资源时,例如sys.stdout,这个时候是需要线程同步来确保资源访问不冲突,GIL不提供类似资源的保护吗?

回复内容:

GIL也只是相当于古时候单核CPU通过不断的分配时间片来模拟多线程的方法而已,为什么那个时候写多线程也要用锁? 这在网上都说烂了. 不过我当初也思考了这个问题一会儿.
你自己想想看这个情景
线程AB同时操作list
list的[0]初始值为0

线程A 操作100次
list[0]+=1
线程B 操作100次
list[0]+=1

在线程A 对于 list[0]进行操作时
list[0]为0, 还没等线程A完成加一操作, 就被切换到线程B了
在线程B 眼里,
list[0]还是为0, 于是执行加一操作.
再切换回线程A, 继续未完成的加一操作

你发现了没!!! 线程AB各对list[0]进行了加一,预期结果是2 但结果还是1
Python的list不是完全线程安全的.

所以加个线程锁就完了.
话说为什么, 有了线程锁还需要GIL呢?
因为, 有了GIL, 提供并发就变得很容易. 解释器只要计算每个线程的运行时间就好了
时间一到, 将这个线程冻结, 内存管理很简单.

等等, 你还是没解释, 如果我已经给线程上了锁, 为什么还是要被GIL限制?
一向符合人类直觉的Python, 有个很反直觉的机制.
Py的变量a其实不是C系编译语言的变量.
Python维护着一个字典, 储存着a和对应数值的指针.

用某黑Python的大牛的话说, Python企图用字典装下世界..
如果变成真多线程
对于这个字典的维护将会很复杂.
多个线程真正同时操作一个字典, Python引以为傲的字典性能, 估计就没那么强了.
就是说, Python字典的性能强大,是建立在线程不安全的基础上.
而字典在Python中的位置又是如此重要, 一个缓慢的字典, 会严重拖慢Python的解释速度.

多线程操作多个独立字典. 那样还是要同步.
那为什么不采用多进程呢? 这就是社区主流的看法.
虽然理论上线程成本更低, 但是那样代码就改成面目全非了.. GIL 的作用是:对于一个解释器,只能有一个thread在执行bytecode。所以每时每刻只有一条bytecode在被执行一个thread。GIL保证了bytecode 这层面上是thread safe的。

但是如果你有个操作比如 x += 1,这个操作需要多个bytecodes操作,在执行这个操作的多条bytecodes期间的时候可能中途就换thread了,这样就出现了data races的情况了。

比如这小家伙就有很多条bytecodes:

>>> dis.dis(lambda x: x+1)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               1 (1)
              6 BINARY_ADD
              7 RETURN_VALUE
youtube.com/watch? gil控制的是字节码, 锁控制的是python代码,粒度不一样吧? 比如用锁控制的代码被编译成101条字节码 那么线程在执行这101条字节码的时候,cpu会被其他线程利用(python调度线程默认是100条字节码 调度一次)
——《Python源码剖析》 GIL是全局解释器锁,GIL保证了在同一时间片下总有一个Python(CPython实现)线程在执行。所以即使是多进程,而是顺序执行的。这样多线程并发就变得没有意义。

  • 线程在GIL下是有执行的时间片的
    • 在时间片内线程如果没有成功对数据进行操作,那么等到下一个时间片时,数据已经被别的线程修改了,那么得到的数据就不是想要的数据了
  • 线程的同步和互斥解决的是线程间数据的访问正确性问题,而GIL是实现当前Python解释器下只有一个线程在执行。两个是不同的概念。

推荐阅读
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 安装mysqlclient失败解决办法
    本文介绍了在MAC系统中,使用django使用mysql数据库报错的解决办法。通过源码安装mysqlclient或将mysql_config添加到系统环境变量中,可以解决安装mysqlclient失败的问题。同时,还介绍了查看mysql安装路径和使配置文件生效的方法。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 禁止程序接收鼠标事件的工具_VNC Viewer for Mac(远程桌面工具)免费版
    VNCViewerforMac是一款运行在Mac平台上的远程桌面工具,vncviewermac版可以帮助您使用Mac的键盘和鼠标来控制远程计算机,操作简 ... [详细]
  • 生成对抗式网络GAN及其衍生CGAN、DCGAN、WGAN、LSGAN、BEGAN介绍
    一、GAN原理介绍学习GAN的第一篇论文当然由是IanGoodfellow于2014年发表的GenerativeAdversarialNetworks(论文下载链接arxiv:[h ... [详细]
  • 信息安全等级保护是指对国家秘密信息、法人和其他组织及公民的专有信息以及公开信息和存储、传输、处理这些信息的信息系统分等级实行安全保护,对信息系统中使用的信息安全产品实 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 去掉空格的方法——Python工程师招聘标准与实践
    本文介绍了去掉空格的方法,并结合2019独角兽企业招聘Python工程师的标准与实践进行讨论。同时提供了一个转载链接,链接内容为更多相关信息。 ... [详细]
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • 本文详细介绍了C语言中的格式化字符串类型,包括浮点数、十六进制数字、p-计数法、十进制整数、小数形式、实数、有符号整数和输出字符串等。对于每种类型,都给出了详细的解释和示例。通过本文的学习,读者将对C语言中的格式化字符串类型有更深入的理解。 ... [详细]
author-avatar
你是我的小二郎
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有