1.全局解释器锁: 保证同意时间仅有一个线程对资源有操作权限
作用:在一个进程内,同一时刻只能有一个线程通过GIL锁被CPU调用,切换条件:I/O操作、固定时间**(系统决定)**。
说明:python多线程中GIL锁只是在CPU操作才是串行的,其他都是并行,所以比串行快很多。
1.为了解决不同线程同时访问同一资源时,数据保护问题,而产生的了GIL。
2.GIL在解释器的层面限制了程序在同一时间只有一个线程被CPU实际执行,而不管你的程序里实际开了多少条线程
3.为了解决这个问题,CPthon自己定义了一个全局解释器锁,同一时间仅仅有一个线程可以拿到这个数据。
4.python之所以会产生这种不好的状况是因为python启用一个线程是调用操作系统原生线程,就是C接口。
5.但是这仅仅是CPython这个版本的问题,在PyPy,中就是没有种缺陷。
用户锁:线程锁:
当前线程还未操作完成前其他多有线程都无法对其操作,及时已经释放了GIL锁
1.在有GIL锁时为何还需要用户锁?
GIL锁只能保证同一时间只能有一个线程对每个资源操作,但当前线程计算完成主动释放锁,其他线程才能对其操作。
2.线程锁的原理
当一个线程对某个资源进行CPU计算的操作时加一个线程锁,只有当前线程计算完成主动释放锁,其他线程才能对其操作。
这样就可以防止还未计算完成,释放GIL锁后其他线程对这个资源操作导致混乱问题。
3.使用线程锁解决上面问题的原理?
在GIL锁中再加一个线程锁,线程锁是用户层面的锁。
线程锁就是一个线程在对数据操作前加一把锁,防止其他线程法制或者这个数据,
只有这个线程对数据操作完毕后才会释放这个锁,其他线程才能操作这个数据。
死锁
1. 死锁定义
1.因争夺资源而造成的一种互相等待的现象。
2. 死锁举例
1. 启动5个线程,执行run方法,假如thread1首先抢到了A锁,此时thread1没有释放A锁,紧接着执行代码mutexB.acquire(),抢到了B锁,在抢B锁时候,没有其他线程与thread1争抢,因为A锁没有释放,其他线程只能等待。
3.使用递归锁解决死锁问题
1.递归锁的作用是同一线程中多次请求同一资源,但是不会参数死锁。
2.这个RLock内部维护着一个Lock和一个counter变量。counter记录了acquire的次数,从而使得资源可以被多次require。
3.直到一个线程所有的acquire都被release,其他的线程才能获得资源。