Python 3.11 版本是对线程安全做了什么更改吗

这篇具有很好参考价值的文章主要介绍了Python 3.11 版本是对线程安全做了什么更改吗。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  • 问题:这份代码在 3.11.3 中它居然输出 0 ,一度以为自己写错了,抱着不信邪的态度,又搞了个 Python 3.9.7 的环境试了下,果然还是符合自己预期,输出不为 0,想问下 3.11 版本中是做了什么修改吗?
import threading

num = 0


def add():
    global num
    for i in range(10_000_000):
        num += 1


def sub():
    global num
    for i in range(10_000_000):
        num -= 1


if __name__ == "__main__":

    add_t = threading.Thread(target=add)
    sub_t = threading.Thread(target=sub)

    add_t.start()
    sub_t.start()

    add_t.join()
    sub_t.join()

    print("num result : %s" % num)

  • 答案:
    1. 首先在 Python 字节码执行的时候 ,GIL 并不是随时能在任意位置中断切换线程。只有在主动检测中断的地方才可能发生线程切换。这个是大前提

    2. 3.10 之前的版本中,INPLACE_ADD 这个 opcode 之后 GIL 会去主动监测中断,所以导致现成不安全。3.10 的代码中有一个提交,https://github.com/python/cpython/commit/4958f5d69dd2bf86866c43491caf72f774ddec97
      根据 T. Wouters 的 Twitter 描述 https://twitter.com/Yhg1s/status/1460935209059328000
      这次提交修改了 INPLACE_ADD 之后主动监测中断的操作。使得 INPLACE_ADD 之后无论如何都不会发生线程切换,因此虽然是两个 opcode ,但是确实是线程安全。

    3. 因为字节码中+=的操作是两步 opcode 操作,且 INPLACE_ADD 之后 GIL 会主动监测中断,导致虽然加了,但是没有重新赋值,就切换到了别的线程上**。比如 A 线程 当前 num=100 。+=1 之后 101 但是买没来得及重新赋值给 num ,GIL 切换了线程,再 B 线程中 num 还是 100 ,-=之后就是 99 ,但是这个线程却赋值给了 num ,此时 num 就是 99 然后又且回了 A 线程**。结果线程将中断时候的 101 赋值给了 num 导致此时 num 变成了 101 就出现问题了

    4. 3.10 以后就不会出现这个问题了,因为 INPLACE_ADD 操作之后 GIL 不再会主动检测中断,意味着正常情况下执行完+=之后线程不会被切换,而是正确执行了赋值给 num 的操作文章来源地址https://www.toymoban.com/news/detail-698772.html

到了这里,关于Python 3.11 版本是对线程安全做了什么更改吗的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python3.8,3.9,3.10,3.11特性比较

    最近计划将python2迁移到python3,由于本人学习时用的3.7版本,所以仅作大于3.7版本的比较。 文档地址:python3.8 作用:避免重复调用,使代码更加简洁。PS:别当GO写,它不支持声明并赋值变量 作用: 新增了一个函数形参语法 / 用来指明某些函数形参必须使用仅限位置而非关键

    2024年02月05日
    浏览(62)
  • 安装python 3.11以及安装pip过程-是安装embedded纯净版的python

    为了纯净,我在Win10上选择安装了embedded的版本的python 3.11,结果为了安装pip倒腾了一早上。现记录如下。 一、安 装python 3.11 从python官网下的,今天的版本是3.11.1,链接:https://www.python.org/ftp/python/3.11.1/python-3.11.1-embed-amd64.zip,下好之后,解压到一个文件夹就行,我的本地文件

    2024年02月17日
    浏览(54)
  • Python及Pycharm专业版下载安装教程(Python 3.11版)附JetBrains学生认证教程

    本篇主要介绍Python和PyCharm专业版的下载及安装方式,以及通过两种方式进行JetBrains学生认证。 1.1、进入python官网:https://www.python.org 点击【Downloads】然后选择需要下载的平台,这里以【Windows】为例。 1.2、在该页面选择要下载的版本。这里选择的是64位稳定发布3.11.8版本。具

    2024年04月11日
    浏览(47)
  • 网络基础3.11

    A (7层)应用层:        输入搞基语言指令(打开微信输入聊天的话语 人和程序之间的一个交流平) (6层)表示层:        将人类是使用的 高级语言翻译成二进制语言 (5层)会话层:        管理多个会话,保证消息正确到达 指定主机 (4层)传输层:    

    2024年03月26日
    浏览(49)
  • 3.11 C结构体及结构体数组

    结构体的意义 问题:学籍管理需要每个学生的下列数据:学号、姓名、性别、年龄、分数,请用C语言程序存储并处理一组学生的学籍。 思考:如果有多个学生,该怎么定义 已学数据类型无法解决。 结构体概述  正式: 结构体是由一批数据组合而成的结构型数据。组成结构

    2024年02月02日
    浏览(32)
  • 线程池-手写线程池C++11版本(生产者-消费者模型)

    本项目是基于C++11的线程池。使用了许多C++的新特性,包含不限于模板函数泛型编程、std::future、std::packaged_task、std::bind、std::forward完美转发、std::make_shared智能指针、decltype类型推断、std::unique_lock锁等C++11新特性功能。 本项目有一定的上手难度。推荐参考系列文章 C++11实用技

    2024年02月13日
    浏览(44)
  • Maven项目中的依赖出现版本冲突,最终发现是对Dependency Scope理解有误

    再来个文章目录 本文记录一下遇到maven依赖版本冲突后的排查过程说明以及问题原因说明 下面还有投票,帮忙投个票👍 最近加入了 Apache Dubbo 开源社区,成为了一名Dubbo Contributor。在熟悉Dubbo中的各个RPC协议时根据官网提供的示例搭建了一个示例。在熟悉过后想看下谷歌提供

    2023年04月09日
    浏览(57)
  • 后端开发必知的11个线程安全小技巧

      对于从事后端开发的同学来说,线程安全问题是我们每天都需要考虑的问题。   线程安全问题通俗地讲主要是在多线程的环境下,不同线程同时读和写公共资源(临界资源)导致的数据异常问题。   比如:变量a=0,线程1给该变量+1,线程2也给该变量+1。此时,线程3获取

    2024年02月15日
    浏览(43)
  • ArrayList为什么不是线程安全的,如何保证线程安全?

    官方曰, 线程安全就是多线程访问时,采⽤了加锁机制,当⼀个线程访问该类的某个数据时,进⾏保护,其他线程不能进⾏访问直到该线程读取完,其他线程才可使⽤。不会出现数据不⼀致或者数据污染。线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数

    2024年02月07日
    浏览(62)
  • 面试题:HashMap线程不安全 ConcurrentHashMap为什么线程安全

    面试的时候先会喊你说说集合,那些集合线程不安全?当你说了 HashMap 线程不安全,面试官可能会进一步询问你是否了解 ConcurrentHashMap ,以及它是如何实现线程安全的。 ArrayList、LinkedList、TreeSet、HashSet、 HashMap 、TreeMap等都是线程不安全的。 HashTable 是线程安全的。 来看个例

    2024年04月23日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包