Python GIL

2022/6/1 1:21:11

本文主要是介绍Python GIL,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

13. GIL
背景:
1. 在CPython解释内部运行多个线程的时候,每个线程都需要解释器内部申请相应的全局资源,
由于C语言本身比较底层造成CPython在管理所有全局资源的时候并不能应对所有线程同时的资源请求,
因此为了防止资源竞争而发生错误,对所有线程申请全局资源增加了限制-全局解释器锁

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

一个进程有且仅有一个的锁,该锁用于控制多线程同一时刻只能有一个线程使用CPU

释放:
GIL锁的释放只需满足以下两个条件中的一个:
1.线程的时间片使用完毕(或者运行完一定行数的字节码)
2.线程遇到阻塞/等待的状态,此时即使时间片没有用完也会释放GIL锁

误区:
1. 有些人会有一个误区,认为一个线程完全执行完才会释放GIL锁给其他线程执行。这样是错的,这样多线程就不是并发而是串行了。
2. 既然CPython解释存在GIL是否意味每个线程在全局变量就不用加Lock互斥锁了呢?
这是一个严重错误的想法,为什么用户操作全局数据还需要加Lock,
因为GIL的释放时机我们无法控制-操作非常可能并没有完成,而不像Lock那样我们用完才释放(操作完整)

14. threading Thread
使用继承Thread的方式要重写run()方法

15. 线程间通信 Queue
Queue相比于普通的list结构而言,Queue是线程安全的,而list不是线程安全的。
原因是Queue内部使用了锁和条件变量来进行线程同步,但是list没有用到线程同步技术

Queue.get() 方法阻塞
Queue的join()方法必须配合task_done()方法一起使用!

Queue的join方法的唤醒条件:
1当队列中所有任务被弹出,队列中元素为0
2.每个被弹出的任务都执行了task_done()来标记这个任务已被完成

两个条件缺一不可

16. 死锁
同一把锁嵌套,锁等待自己这把锁造成死锁;
两把不同的锁嵌套,造成相互等待造成死锁



这篇关于Python GIL的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程