3.2.6 Python的GIL锁内部机制

GIL(Global Interpreter Lock)全局解释器锁

In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.)

在Cpython中,全局解释器锁,或者叫GIL,是一个互斥体,它可以阻止多个来自执行中的Python字节码的本地线程同时运行。这个锁很重要主要是因为CPython的内存管理在线程上不安全。(不管怎样,由于GIL的存在,其他特性已经越来越依赖于它(指GIL)强制实行的保证)

大概意思就是,python的多线程是假多线程,因为有GIL的存在,同一时间CPU(不管你几个核)只能执行一条线程。这个GIL已经不可能去掉了,因为它已经成为了CPython的基石的一部分,CPython其他很多功能都依赖它才能运行。

上面是英文老师说的,说必须依赖;但下面中文老师又说了,说可以完全不依赖。

首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码。有名的编译器例如GCC,INTEL C++,Visual C++等。Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行。像其中的JPython就没有GIL。然而因为CPython是大部分环境下默认的Python执行环境。所以在很多人的概念里CPython就是Python,也就想当然的把GIL归结为Python语言的缺陷。所以这里要先明确一点:GIL并不是Python的特性,Python完全可以不依赖于GIL。

这里不争论,先继续往下走。

这篇文章透彻的剖析了GIL对python多线程的影响,强烈推荐看一下:http://www.dabeaz.com/python/UnderstandingGIL.pdf

下面这个示例很好的解释了GIL

import threading
import time

start_time = time.time()
def run(n):
    global num
    time.sleep(0.8)
    num += 1

num = 0
t_l = []    #存放线程
for i in range(10000):
    t = threading.Thread(target=run, args=(‘t-%s‘ % i, ))
    t.start()
    t_l.append(t)    #为了不阻塞其他线程的启动,先放在列表里,最后join

for t in t_l:    #循环线程列表,执行所有线程
    t.join()

print(‘All threads have ran down!‘, threading.current_thread(), threading.activeCount())
time.sleep(0)
#current_thread显示当前线程
#activeCount显示活动的线程数
print(‘Num: ‘, num)
print(‘Total Cost: ‘, time.time() - start_time)

运行结果

All threads have ran down! <_MainThread(MainThread, started 2848)> 1
Num:  10000
Total Cost:  2.0331716537475586

windows下计算正确,但在Ubuntu Linux或MAC OS上可能会出现计算错误的情况。所以,为什么会计算错误呢?看下图

  1. 全局变量num经过图中前5步的执行,到第5步(由于CPU切换上下文所设定的时间)GIL被强制释放。但此时并未完成num+1,所以num此时还是0。
  2. 6-11步调用num,完成num+1,并赋值给num,释放GIL,此时num=1。
  3. 11-13步调用num,重复之前1-4接13步,这次完成num+1运算,num=2。

亲,我这笔记写的这么好,你看懂了吗?

原文地址:https://www.cnblogs.com/infinitecodes/p/12122225.html

时间: 2024-07-30 12:08:28

3.2.6 Python的GIL锁内部机制的相关文章

对于Python的GIL锁理解

GIL是什么 首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念.就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码.有名的编译器例如GCC,INTEL C++,Visual C++等.Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行.像其中的JPython就没有GIL.然而因为CPython是大部分环境下默认的Python执行环境.所以在很多

python的GIL锁

进程:系统运行的一个程序,是系统分配资源的基本单位. 线程:是进程中执行运算的最小单位,是处理机调度的基本单位. 处理机:是计算机中存储程序和数据,并按照程序规定的步骤执行指令的部件.包括中央处理器.主存储器.I/O接口. 程序:程序是描述处理机完成某任务的指令序列. 指令:处理机能够解释.直接执行的信息单位. 计算机系统:处理机+外围设备. 并行:多个cpu同时执行多个任务,假设有两个程序,这两个程序在两个不同的cpu上同时运行. 并发:单个cpu交替执行多个任务,假设有两个程序,这两个在该c

python GIL锁 锁 线程池 生产者消费模型

python的GIL 锁 python内置的一个全局解释器锁 , 锁的作用就是保证同一时刻一个进程中只有一个线程可以被cpu调度 为什么有这把GIL锁? python语言的创始人在开发这门语言时 , 目的快速把语言开发出来 , 如果加上GIL锁(C语言加锁) , 切换时按照100条字节指令来进行线程间的切换 锁 : 1.锁 : Lock(1次放1个) 线程安全 , 多线程操作时 , 内部会让所有线程排队处理 , 如 : list / dict / Queue 线程不安全 + 人  =>排队处理

python学习第37天GIL锁、死锁现象与递归锁、信号量、Event时间、线程queue

一.GIL锁 1. 什么是GIL全局解释器锁 定义: In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython's memory management is not thread-safe

python网络编程--线程(锁,GIL锁,守护线程)

1.线程 1.进程与线程 进程有很多优点,它提供了多道编程,让我们感觉我们每个人都拥有自己的CPU和其他资源,可以提高计算机的利用率.很多人就不理解了,既然进程这么优秀,为什么还要线程呢?其实,仔细观察就会发现进程还是有很多缺陷的,主要体现在两点上: 进程只能在一个时间干一件事,如果想同时干两件事或多件事,进程就无能为力了. 进程在执行的过程中如果阻塞,例如等待输入,整个进程就会挂起,即使进程中有些工作不依赖于输入的数据,也将无法执行. 如果这两个缺点理解比较困难的话,举个现实的例子也许你就清楚

Python并发编程05/ 死锁/递归锁/信号量/GIL锁/进程池/线程池

目录 Python并发编程05/ 死锁/递归锁/信号量/GIL锁/进程池/线程池 1.昨日回顾 2.死锁现象与递归锁 2.1死锁现象 2.2递归锁 3.信号量 4.GIL全局解释器锁 4.1背景 4.2为什么加锁 5.GIL与Lock锁的区别 6.验证计算密集型IO密集型的效率 6.1 IO密集型 6.2 计算密集型 7.多线程实现socket通信 7.1服务端 7.2客户端 8.进程池,线程池 Python并发编程05/ 死锁/递归锁/信号量/GIL锁/进程池/线程池 1.昨日回顾 #生产者消

Python 之 GIL 全局解释器锁

GIL(全局解释器锁) GIL锁即全局解释器锁,是 CPython 解释器的特性.它的作用是保证了同一时刻只有一个线程执行 Python 字节码. 它并不是 Python 的特性,它的存在是 CPython 的内存管理机制导致的.语言的内存管理机制一般有两种:1.引用计数 2.垃圾回收.CPython 用的就是引用计数来管理内存.当一个资源的引用次数为0时,就将这个对象释放.如果没有 GIL 锁,在多线程中即时简单的操作也可能引起变量被多个线程同时修改,这样显然会容易出错. 那么 GIL 锁会导

Python 线程----线程方法,线程事件,线程队列,线程池,GIL锁,协程,Greenlet

主要内容: 线程的一些其他方法 线程事件 线程队列 线程池 GIL锁 协程 Greenlet Gevent 一. 线程(threading)的一些其他方法 from threading import Thread import threading import time def work(): time.sleep(1) print("子线程对象>>>", threading.current_thread()) # 子线程对象 print("子线程名称>

python GIL锁、进程池与线程池、同步异步

一.GIL全局解释器锁 全局解释器锁 在CPython中,全局解释器锁(GIL)是一个互斥锁,它可以防止多个本机线程同时执行Python代码.之所以需要这个锁,主要是因为CPython的内存管理不是线程安全的.(然而,自从GIL存在以来,其他特性已经逐渐依赖于它所执行的保证) 什么是GIL 全局解释器锁, 施加在解释器上的互斥锁 为什么需要GIL 由于CPython的内存管理时非线程安全,于是CPython就给解释器加上锁, 解决了安全问题. GIL的加锁与解锁时机 加锁的时机: 在调用解释器时