Python中的GIL(笔记+)

首先,我们要搞清楚的一些概念。

程序:程序员开发的代码,还没有运行,保存在磁盘中的。

进程:运行中的程序,需要耗费电脑的CPU,内存等资源。

线程:线程是进程中执行运算的最小单位,是进程中的一个实体,是被系统独立调度和分派的基本单位,

线程自己不拥有系统资源,只拥有一点儿再运行中必不可少的资源,但它可与同属一个进程的其他线程

共享进程所拥有的全部资源。一个线程可以创建和撤销另一个线程,同一进程中的多个线程之间可以并发执行。

如果把程序比喻成一个酒店,那么进程就是包房。(包房里面有空调,厕所,桌子等)。

线程就是包房里面的一套桌子。

线程和进程的关系及区别?

进程和线程的关系:

(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。(这个好理解,一个桌子可肯定属于某个包房,一个包房可以有多张桌子,最少有一张)

(2)资源分配进程,同一进程 的所有线程共享该进程的所有资源。(资源按照包房分,同一个包房的共享空调,测试等)

(3)处理机分给线程,即真正在处理机上运行的是线程(真正用来吃饭的就是桌子)

(4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。

线程是指进程内的一个执行单元,也是进程内的可调度实体。

进程与线程的区别:

(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位。

(这个好理解,桌子是吃饭基本的分配单位,包房是资源的基本单位)

进程不能单独执行,它只是资源的集合。

进程要操作CPU,必须要先创建一个线程。

所有在同一个进程里的线程,是同享同一块进程所占的内存空间。

(2)并发性:不尽进程之间可以并发执行,同一个进程的多个线程之间也可并发执行。(好理解,不同包房可以同时开饭,同一个包房不同桌也可以同时开饭。

(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源。

(你定了包房,就定了里面的资源和服务,要多算钱的,每桌客人都可以公用包房里的东西)

(4)系统开销:在创建或撤销进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤销线程时的开销。

(一个包房的开销,肯定比一个桌的开销大)

并行:多个CPU同时执行多个任务,就好像有两个程序,这两个程序是真的在两个不同的CPU内同时执行。(比如有两个服务员,同时服务两个包房)

 

并发:CPU交替处理多个任务,还是有两个程序,但是只有一个CPU,会交替处理这两个程序,而不是同时执行,只不过因为CPU执行的速度过快,而会使得人们感到是在“同时执行,执行的先后取决于各个程序对于世间片资源的争夺。

并发其实是串行。(如同有一个服务员,同时服务一个包房的两桌,由于速度快,两桌看起来似乎同时开饭。

实际上有先后,只是世间太短,只是世间太短,看不出来)

 

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

首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。

并行和并发同属于多任务,目的是要提高CPU的使用效率。这里需注意的是,一个CPU永远不可能实现并行,

即一个CPU不能同时运行多个程序,但是可以随机在随机分配的时间片内交替执行(并发),

就好像一个人不能同时看两本书,但是却能够先看第一本书半分钟,再看第二本书半分钟,这样来回切换。

Guido van Rossum(吉多.范罗苏姆)创建Python时就只考虑到单核cpu,解决多线程之间数据完整性和状态同步的

最简单方法就是加锁,于是有了GIL这把超级大锁,因为cPython解析只允许拥有GIL全局解析器锁才能运行程序,

这样就保证了同一个时刻只允许一个线程可以使用cpu。由于大量的程序开发者接收了这套机制,现在代码量越来越多,

已经不容易通过c代码去解决这个问题。

每个线程在执行时候都需要先获取GIL,保证同一时刻只有一个线程可以执行代码,即同一时刻只有一个线程使用CPU,也就是说多线程并不是真正意义上的同时执行。

多线程如同客人要用包房里的厕所,一次只能一个人用。进去的人把门锁住。用完释放,下一个人接着用。

进程如同独立包房,一个厕所够了,不要排队,也就不需要锁了。

那么,我们该如何解决GIL锁的问题呢?

1.更换cpython为ipython(不建议)

2.使用多进程完成多线程的任务

3.在使用多线程可以使用c语言去实现

以下是几个面试遇到的问题,希望对大家有所帮助:

问题1:什么时候会释放GIL锁

答:1.遇到像i/o操作这种,会有时间空闲情况造成cpu闲置的情况会释放GIL;

2.会有一个专门ticks进行计数,一旦ticks数值达到100这个时候释放GIL锁,线程之间开始竞争GIL锁

(说明:ticks这个数值可以进行设置来延长或者缩减获得GIL锁的线程使用cpu的时间)

问题2:互斥锁和GIL的关系

GIL锁:保证同一时刻只有一个线程能使用到CPU

互斥锁:多线程时,保证修改共享数据时有序的修改,不会产生数据修改混乱

GIL与多线程

1.进程可以 利用多核,但是开销大。

2.多线程开销小,却无法利用多核优势。

也就是说Python中的多线程是假的多线程,Python解释器虽然可以开启多个线程,但同一时间只有一个线程能在解释器中执行,而做到这一点正是由于GIL锁的存在,它的存在使得CPU的资源同一时间只会给一个线程使用,而由于开启线程的开销小,所以

多线程才能有一片用武之地,不然就真的是鸡肋了。

而Python的多线程到底有没有用,我们需要看任务是I/O密集型,还是计算密集型:

如果是I/O密集型任务,有再多核也没用,即能开再多进程也没用,所以利用Python的多线程一点问题也没用;

如果是计算密集型任务,我们就直接使用多进程就可以了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值