python 对象锁_也许你对 Python GIL 锁的理解是 错的。

84be82b1b10528633f0e752df0134e79.png

摄影:产品经理甜白与草莓更配~

我刚到现在这个公司时,听到当时一个高级工程师(现已离职)大声地跟他旁边的同事说:

Python 有 GIL 锁,所以它的多线程实际上是单线程,所以写多线程代码不用考虑线程冲突,不用加锁。

相信现在看这篇文章的同学,不少人也是这样认为的。

然而,我要告诉你的是,这句话前半句是对的,后半句是 错的。Python 的多线程确实本质上是单线程。但你依然需要考虑线程并发冲突。

我们来举个例子:

场景 1:单线程

变量 a 的值为1.代码读取 a 的值,把它加 1 变成2.然后把2重新赋值给 a。代码再次读取 a 的值,把它加 1 变成3.然后重新把3复制给 a。最终 a 的值是3.

场景 2:伪多线程

Python 的多线程是伪多线程,意味着在微观上它是单线程。同一个时间,只有一个线程在运行,其他线程是暂停的状态。现在有一个变量 a,它里面的值为1.

  1. 线程 1 从 a 里面获取到1,把它加1,线程 1 还没有来得及把数字2重新赋值给变量 a 时,时间片切换到线程 2.
  2. 此时线程 1 暂停。线程 2 去读取变量 a,这个时候的 a 依然是1.线程 2 也把这个数字加1,变成2.
  3. 时间片切换到线程 1,线程 2 暂停。线程 1 把数字2赋值给变量 a,此时 a 的值变成2.
  4. 时间片切换到线程 2,线程 1 暂停。线程 2 把数字2赋值给变量 a,此时 a 的值还是2.

可以看到,即使同一时间只有一个线程在运行,但是两个线程同时修改同一个变量时,也会发生并发冲突。

GIL 到底锁的是什么?

大家都说 Python 有 GIL 锁,那么这个锁到底锁的是什么东西??

GIL 的全称是 Global Interpreter Lock, 全局解释器锁。它锁的是解释器而不是你的 Python 代码。它防止多线程同时执行 Python 的字节码(bytecodes),防止多线程同时访问 Python 的对象。

在 Python 官方文档Releasing the GIL from extension code[1]中,有这样一段话:

Here is how these functions work: the global interpreter lock is used to protect the pointer to the current thread state. When releasing the lock and saving the thread state, the current thread state pointer must be retrieved before the lock is released (since another thread could immediately acquire the lock and store its own thread state in the global variable). Conversely, when acquiring the lock and restoring the thread state, the lock must be acquired before storing the thread state pointer.

其中加黑的这一句话是说:GIL 锁用来保护指向当前进程状态的指针。

再看文档Thread State and the Global Interpreter Lock[2]中提到的这样一句话:

Without the lock, even the simplest operations could cause problems in a multi-threaded program: for example, when two threads simultaneously increment the reference count of the same object, the reference count could end up being incremented only once instead of twice.

当两个线程同时提高同一个对象的引用计数时,(如果没有 GIL 锁)那么引用计数只会被提高了 1 次而不是 2 次。

大家注意我这两段应用中的指针引用计数。其中指针是 C 语言的概念,Python 没有指针;引用计数是 Python 底层的概念。你平时写的 Python 代码,引用计数是在你调用变量的时候自动增加的,不需要你去手动加 1.

所以 GIL 锁住的东西,都是不需要你的代码直接交互的东西。

Python 的解释器通过切换线程来模拟多线程并发的情况,如上面举的例子,虽然同一个时间只有一个线程在活动,但仍然可以导致并发冲突。

所以,以后不要再说出 Python 不需要解决并发冲突这种话了。

参考资料

[1]

Releasing the GIL from extension code: https://docs.python.org/3/c-api/init.html#releasing-the-gil-from-extension-code

[2]

Thread State and the Global Interpreter Lock: https://docs.python.org/3/c-api/init.html#thread-state-and-the-global-interpreter-lock

a45bdca81d97dd0680945fc004551c1b.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/346248.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux下强制取消nfs挂载目录,强制卸载无响应的nfs挂载目录

强制卸载无响应的nfs挂载目录在日常的运维中, 经常有需要使用 nfs 挂载远程服务器目录的需求, 但是照我个人实际使用的经验来看, nfs 并不是"一劳永逸", 故障率还是蛮高的, 其中最长遇到的就是由于网络原因/远程 nfs 服务器原因或其他原因导致的 nfs 客户端与 nfs 服…

animals中文谐音_Animals谐音歌词,Maroon5《animals》英语歌曲中文音译

歌词谐音:Maroon 5《Animals(野性)》-音吧网英语歌曲谐音歌词中文音译原创词:本尼布兰克曲:亚当莱文,本尼布兰科,谢尔贝克,史奇雷克斯所属专辑:《冰雪奇缘》电影原声带音吧网-www.yinbawang.com…

服务性服务–服务到服务的通话

在上一篇文章中,我介绍了如何使用Knative的 Serving功能来运行示例Java应用程序。 这篇文章将介绍部署两个应用程序的步骤,其中一个应用程序调用另一个。 样品细节 整个示例可在我的github存储库中找到– https://github.com/bijukunjummen/sleuth-webf…

linux cookie 地址,SYN Cookie原理及其在Linux内核中的实现

在目前以IPv4为支撑的网络协议上搭建的网络环境中,SYN Flood是一种非常危险而常见的DoS攻击方式。到目前为止,能够有效防范SYN Flood攻击的手段并不多,而SYN Cookie就是其中最著名的一种。SYN Cookie原理由D. J. Bernstain和 Eric Schenk发明…

maya中英文对比_maya中英文对照表

1File文件New Scene建立新场景Open Scene打开场景Save Scene存盘场景Save Scene As改名存盘Import导入Export All导出所有Export Selection导出选定物体View Image查看图片View Sequence浏览顺序Create Reference引入场景文件Reference Editor引入场景编辑器Project项目New建立…

linux vmcore 分析,crash分析vmcore

然后进入 /var/crash/ 找到相应的vmcore执行crash 127.0.0.1-2014-01-21-23\:36\:14/vmcore /usr/lib/debug/lib/modules/2.6.32-902.279.9.1.***.el6.x86_64/vmlinux输出如下:KERNEL: /usr/lib/debug/lib/modules/2.6.32-902.279.9.1.***.el6.x86_64/vmlinuxDUM…

用置换破坏您的JUnit5测试

编写JUnit测试可能是一个乏味而乏味的过程。 了解如何使用排列结合TestFactory方法和DynamicTest对象以最少的编码工作来改进测试类。 在本文中,我将使用Java流ORM Speedment,因为它包含一个现成的Permutation类,从而帮助我节省了开发时间。…

es6 遍历数组对象获取所有的id_ES6对象遍历Object.keys()方法

【Object.keys()】ES5 引入了Object.keys()方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名var obj { foo: bar, baz: 42 };console.log(Object.keys(obj));// ["foo", "baz"]ES2017 引入了跟…

servlet异步_如何使用异步Servlet来提高性能

servlet异步这篇文章将描述一种性能优化技术,该技术适用于与现代Web应用程序相关的常见问题。 如今的应用程序不再只是被动地等待浏览器发起请求,而是希望自己开始通信。 一个典型的示例可能涉及聊天应用程序,拍卖行等–共同点是这样一个事实…

mysql锁机制 php_MySQL锁机制和PHP锁机制

模拟准备--如何模拟高并发访问一个脚本:apache安装文件的bin/ab.exe可以模拟并发量 -c 模拟多少并发量 -n 一共请求多少次 http://请求的脚本例如:cmd: apache安装路径/bin/ab.exe -c 10 -n 10 http://web.test.com/test.php【切入正题】MYSQ…

怎么安装红旗Linux5,如何用硬盘安装红旗LINUX5_0.doc

如何用硬盘安装红旗LINUX5_0如何用硬盘安装红旗LINUX5_0本文由xinbing9贡献红旗linux5.0安装教程相信大家都和我一样,在一开始知道linux的系统时充满了神秘感.习惯了windows的我们对另一种操作系统非常好奇.正是这种好奇心,我决定装linux.看看到底有什么东东.第一次装时,大略的…

企业应用程序开发框架的分类

如果您使用的是“最佳Java框架”,那么您很可能会迷失本文 ,它对Java Enterprise世界中的情况进行了很好的概述。 但是,从我的角度来看,它缺少一件非常重要的事情–对上述框架进行分类。 让我们看看这个生态系统的另一个角度&…

投资最重要的事读后感_《投资最重要的事》读书笔记分享

1、学习第二层次思维。在投资的零和世界中参与竞争之前,你必须先问问自己是否具有处于上半部分的充分理由。要想取得超过一般投资者的成绩,你必须有比群体共识更加深入的思考。你具备这样的能力吗?是什么让你认为自己具有这样的能力&#xff…

Linux下社交平台,Linux 启动

> 1. 如启动失败请 查看[坑点概述](https://doc.fastadmin.net/wanlshop/299.html)## Linux运行IM即时通讯#### 1\. 远程连接Linux可以通过远程连接软件、VNC远程连接、Workbench或宝塔面板 > 软件商店 > 宝塔SSH终端进入SSH 终端cd命令 进入cd www/wwwroot/你的网站/…

vscode 取消拉去变基_GIT快速回忆

关于GIT和github:请搜索git下载安装,安装了git才能去github或码云(国内)观察自己上传的代码,github有个桌面版只是基于git的的图形工具,还是需要下载git。概念:1.提交、版本、commit,ID,差不多都…

java对象序列化去掉字段_使用序列化查找对象中的脏字段

java对象序列化去掉字段假设您正在开发一个将对象自动保存到数据库中的框架。 您需要检测两次保存之间所做的更改,以便仅保存已修改的字段。 如何检测脏场。 最简单的方法是遍历原始数据和当前数据,并分别比较每个字段。 代码如下: public s…

c语言中怎么定义的字符串,C语言中定义字符串的几种方式

1,什么是字符串?所谓字符串本质上就是以\0作为结尾的特殊字符数组;2,定义字符串的过程中有哪些注意点由于字符串本质上其实就是以\0作为结尾的特殊字符数组,所以定义字符串时,必须保证字符串存储的最后一个…

ios 不被遮挡 阴影_解决ios10导航栏底部阴影线条隐藏失效问题

2016.11.13 21:47* 字数 887 阅读 791评论 0喜欢 16一、置空阴影图片基于iOS9,在iOS10上不好使.[self.navigationController.navigationBar setShadowImage:[UIImage new]];二、剪裁navigationBar首先看看UIView的clipsToubounds属性在SDK中的描述:property(nonatom…

Java的未来项目:巴拿马,织布机,琥珀和瓦尔哈拉

新闻稿“ Oracle Code One Java主题演讲概述了Java的未来 ”在Oracle Code“突出未来项目” Valvala 项目,巴拿马 项目,Amber 项目和Loom 项目中描述了Java主旨。 这篇文章为不熟悉上述项目的人提供了每个项目的简要摘要以及与每个项目相关的一些最新工作…

c语言选择题答案在哪查,C语言选择题及答案

C语言选择题及答案成绩的取得离不开我们平时的努力,以下是百分网小编为大家整理的C语言选择题及答案,希望对大家的学习起到帮助!选择题1.在深度为5的满二叉树叶中,叶子结点的个数为( )。A.32B.31C.16D.152.软件生命周期中,花费最多…