python的全局解释器锁GIL
限制了程序的多核执行,同时只有一个线程执行字节码,因此cpu密集型的操作很难利用多核优势,而在io密集型操作时候会释放GIL,因此对i/o密集型操作影响不大
如何规避GIL的影响?
cpu密集型:多进程+进程池
i/o密集型:多线程/协程
cpython扩展(了解)
当线程在进行运行时候GIL会自动上锁,但是为什么还要关注线程的安全
呢?
因为当该线程的操作不是为原子操作的时候,有可能还是会被其他线程覆盖,判断一个方法是不是原子操作可以通过dis库进行检查,原子操作例如
import dis
a=[0]
def add():
a[0] = 1
print(dis.dis(ad))
#打印结果
0 LOAD_CONST 1 (1)
2 LOAD_GLOBAL 0 (a)
4 LOAD_CONST 2 (0)
6 STORE_SUBSCR #只有一个原子操作
8 LOAD_CONST 0 (None)
10 RETURN_VALUE
非原子操作例如
import dis
a=[0]
def add():
a[0] += 1
print(dis.dis(ad))
#打印结果
0 LOAD_GLOBAL 0 (a)
2 LOAD_CONST 1 (0)
4 DUP_TOP_TWO
6 BINARY_SUBSCR
8 LOAD_CONST 2 (1)
10 INPLACE_ADD
12 ROT_THREE
14 STORE_SUBSCR
16 LOAD_CONST 0 (None)
18 RETURN_VALUE
因此在有GIL的时候也不能保证线程之间的安全,需要加锁threading.Lock()