Python-GIL深度理解

2023-11-09

1.GIL介绍

        GIL,意为全局解释器锁,是cPython执行多线程/进程计算密集型代码效果不如人意的主要原因。
        cPython限制一个进程内同时只能执行一个线程。
首先介绍一下,正常多线程/进程执行时,多线程/进程数据混乱的原因:
      cpu分成多个时间片段,启动10线程,分配10个cpu时间片段,当我累加数字设置比较小的时候,在单个cpu时间片段内,for循环代码就执行完,就不会产生数据混乱的。当我数据设置的比较大时,在单个cpu时间片段内,for循环代码就执行不完,并且没有分配2个或2个以上的连续的cpu时间片段,导致一个cpu时间片段没有执行完该线程,下一个线程开始执行了 ​ 原文链接:https://blog.csdn.net/YZL40514131/article/details/126198377

        GIL是CPython才有的限制。

 

    每个进程分配一个cPython解释器,垃圾回收功能也算解释器的一个线程,而且是线程不安全的。
    所以cPython限制一个进程内同时只能执行一个线程,这就是GIL。
    所以可以看出,GIL本质是个线程互斥锁。 GIL会在抢到锁后执行IO操作时被释放,所以IO密集型多线程/进程不受GIL影响,因为GIL会被不断释放。 
    Python的GIL(全局解释器锁)会在执行阻塞IO操作时被释放。这是因为在等待IO操作完成的过程中,Python线程不需要持有GIL,也不需要执行Python字节码。所以,在这种情况下,其他Python线程可以获得GIL并执行代码。

2.测试代码

#多线程执行以下代码,结果正常,因为GIL充当互斥锁。
def task():
    global g_n
    tem=g_n
    # time.sleep(0.05)
    g_n=tem-1
#以上代码等价于
def task():
    global g_n
    mutex.acquire()
    tem=g_n
    # time.sleep(0.05)
    g_n=tem-1
    mutex.release()
#但是time.sleep()执行后,出现数据混乱的问题,因为sleep是io操作,io操作提前释放了该线程的GIL,以至于没有互斥作用
def task():
    global g_n
    tem=g_n
    time.sleep(0.05)
    g_n=tem-1
#所以需要自己手动加上互斥锁
def task():
    global g_n
    mutex.acquire()
    tem=g_n
    time.sleep(0.05)
    g_n=tem-1
    mutex.release()#结果正确

完整测试代码:

import os
import random
import threading
import multiprocessing
import time
from multiprocessing import Process
from threading import Thread
g_n=180#初始值
cnt=int(10)
cpu_cnt=os.cpu_count()
mutex=threading.Lock()
def task():
    global g_n
    mutex.acquire()
    tem=g_n#取出全局变量的值
    # time.sleep(0.05)
    g_n=tem-1#每次减一
    mutex.release()
if __name__ == '__main__':
    l_p=[]
    print("cpu_cnt: ",cpu_cnt)
    for _ in range(cpu_cnt):#创建cpu核数个线程
        t=Thread(target=task)
        t.start()#执行
        l_p.append(t)
    for t in l_p:
        t.join()#同时结束
    print(f"实际为",g_n)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python-GIL深度理解 的相关文章

随机推荐

  • Java Web入门之Ajax的用法详解(附代码和实战)

    创作不易 觉得有帮助或需要源码可以点赞关注收藏后评论区留言 文章目录 前言 一 Ajax与传统的Web应用模式的对比 二 Ajax使用的技术 三 XMLHttpRequest对象的具体使用 四 与服务器通信 发送请求与处理响应 五 Ajax
  • Java最全SSM框架教程-学习笔记

    这里写目录标题 Spring快速入门 Spring优势 Spring开发步骤 Spring配置文件 Spring配置数据源 Spring注解开发 SpringMVC SpringMVC概述 SpringMVC快速入门 SpringMVC注解
  • put_user()函数和get_usr()函数介绍

    1 使用的场景 1 内核地址空间和驱动地址空间是隔绝的 不能使用memcpy 函数 必须使用专门的拷贝函数 2 在拷贝大量数据时使用copy to user 和copy from user 函数 拷贝单个数据时 比如某个int型变量 则优先
  • Vue-Router笔记大全

    Vue Router笔记大全 一 路由的本质和分类 1 路由的本质 2 分类 二 后端路由 1 概念和本质 2 SPA Single Page Application 三 前端路由 1 概念和本质 四 实现简易的前端路由 未使用vue ro
  • React-router v6 在 Class 组件和非组件代码中的正确用法

    最近内部正在开发的 react 项目 react router 全线升级到了 v6 版本 v6 版本中很多 API 进行了重构变更 导致很多旧写法失效 下面记录一下 history 模块在 v6 中的用法 一 在封装的 request 等非
  • 2、进程通信

    进程通信 进程通信 1 进程建通信概述 1 目的 2 来源 3 进程间通讯方式包括 2 管道通讯 1 无名管道 2 命名管道 3 信号通讯 4 共享内存 进程通信 1 进程建通信概述 1 目的 为何需要进程间通信 1 数据传输 一个进程需要
  • MySQL中Index与Key的区别

    看似有差不多的作用 加了Key的表与建立了Index的表 都可以进行快速的数据查询 他们之间的区别在于处于不同的层面上 Key即键值 是 关系模型理论中的一部份 比如有主键 Primary Key 外键 Foreign Key 等 用于 数
  • 计算机网络笔记(四):Socket编程

    文章目录 前言 Socket API 函数 WinSock为例 数据解析 网络字节顺序 解析服务器IP地址 端口号 解析协议号 TCP UDP客户端软件流程 服务器软件设计 前言 几种典型的应用编程接口 Berkeley UNIX操作系统定
  • 赋能数字经济发展的数字政府建设:内在逻辑与创新路径

    数字政府的兴起是政府部门对经济演进到数字形态的自我适应 也是我国深化改革赋能数字经济发展的关键举措 面对数字经济条件下市场体系的特征变化及面临挑战 本文提出 数字政府赋能的核心在于增进市场机能 进而更好发挥出市场作用 赋能的关键在于要素释放
  • Oracle、MySQL 合并重复不需要显示的数据到同一行

    Oracle 原sql SELECT S SOURCE ID S DURATION FROM S TRAININGRECORD S WHERE 1 1 AND S USER CODE 2 ORDER BY S SOURCE ID S STA
  • 有向图的拓扑排序

    有向图的拓扑排序的基本思想是 首先在有向图中选取一个没有前驱的顶点 将其输出 从有向图中删除该顶点 并且删除 以该顶点为尾 的所有有向图的边 重复以上的步骤 直到图中的 所有顶点均输 出或是图中的 顶点均没有前驱 为止 对于后者 说明有向图
  • 网络安全入门学习第五课——MySQL运算函数集合

    文章目录 前言 一 COUNT 二 SUM 三 AVG 四 MAX 五 MIN 前言 MySQL中包括COUNT SUM AVG MAX 和MIN 当需要对表中的记录求和 求平均值 查询最大值和查询最小值等操作时 可以使用集合函数 GROU
  • ModuleNotFoundError: No module named ‘MultiScaleDeformableAttention

    需要编译一下 下载这个项目的代码GitHub fundamentalvision Deformable DETR Deformable DETR Deformable Transformers for End to End Object D
  • LAMP环境的搭建与部署

    目录 一 LAMP是什么 二 LAMP是怎么协同工作的 为什么需要的是这四个组合 三 搭建LAMP环境 gt 部署WEB程序 1 LAMP环境作用 四 LAMP环境搭建过程 1 安装apache 2 安装mysql 一 LAMP是什么 Li
  • Mac 抓包工具 Charles安装和破解教程

    1 环境 mac 10 13 charles 4 2 2 安装 官方地址 https www charlesproxy com 3 破解 1 可以参考CSDN博客上面的破解教程 比如修改charles jar文件或者替换掉原来的软件 2 可
  • 【R语言】——火山图绘制

    本期介绍利用R语言筛选差异表达基因及绘制火山图 一 什么是火山图 火山图 volcano plot 是散点图的一种 它将统计测试中的统计显著性量度 如p value FDR 和变化幅度相结合 从而可以快速直观地识别那些变化幅度较大且具有统计
  • 写一篇关于挠脚心的文章

    挠脚心是一种常见的不适症状 它指的是在脚底部或脚趾处感到刺痛或针刺感 挠脚心可能是由于多种原因引起的 其中常见的原因有 高弓足 高弓足是指脚弓高度过高 导致脚底和脚趾处压力过大 引起挠脚心 足部运动损伤 长期运动或活动过度可能导致脚底和脚趾
  • SDNU 1224.Tom'problem B(迪杰斯特拉)

    Description Tom is a student in Shan Dong Normal University his University in the suburbs this day Tom wanted to go to t
  • 《马克思主义基本原理概论》第 1 章世界的物质性及发展规律

    未完待续
  • Python-GIL深度理解

    1 GIL介绍 GIL 意为全局解释器锁 是cPython执行多线程 进程计算密集型代码效果不如人意的主要原因 cPython限制一个进程内同时只能执行一个线程 首先介绍一下 正常多线程 进程执行时 多线程 进程数据混乱的原因 cpu分成多