ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Python GIL

2022-05-31 18:34:52  阅读:160  来源: 互联网

标签:CPython Python Queue 死锁 线程 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. 死锁
同一把锁嵌套,锁等待自己这把锁造成死锁;
两把不同的锁嵌套,造成相互等待造成死锁

标签:CPython,Python,Queue,死锁,线程,GIL
来源: https://www.cnblogs.com/guxing123/p/16331771.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有