GIL:全局解释器锁

为什么Python多核相当于单核?对于多线程操作同一数据而言

'''
GIL:全局解释器锁
四核:同一时刻真正有四个任务在运行,多核的意义在于此
单核:看上去是并发的,因为进行了上下文切换,单核永远是串行的,并发是假象
Python中不论有多少核都是假象,同一时间执行的线程只有一个。
这是Python开发的时候的设计缺陷。
Python的线程是调用操作系统的c语言的原生线程,
要启动一个线程必须告诉上下文关系(例如书号,行号,第几个字)
例如有一块共享空间:num = 1让四个线程对num加1,他们拿到的上下文都是num=1
如果同时运行,返回的结果,可能为2或其他什么值。
所以这里需要串行。线程1--线程2--线程3--线程4 在Python里不可能实现的
Python解释器把num=1直接给四个线程,相当于四个函数,线程执行过程中,
解释器控制不了四个线程谁先执行,谁后执行。所以Python解释器就控制了出口
同一时间只有一个线程工作,只有一个线程对num加1,这就是全局解释器锁
但是Python四个线程虽然只有一个线程工作,但是可能是均匀分给四个CPU的
所以,如果多个线程同时访问一块数据,这时候同一时间只有一个线程在工作
'''
import threading
import time

class Foo:
    num = 1
    @classmethod
    def run(cls):
        # print("-----begin---")
        time.sleep(2)
        cls.num += 1

t1 = threading.Thread(target=Foo.run, args=())
t2 = threading.Thread(target=Foo.run, args=())
t3 = threading.Thread(target=Foo.run, args=())
start_time = time.time()
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
print(Foo.num)     # 4
print(time.time()-start_time)  #  2.0021145343780518

# 可以看出:
# 1、GIL全局解释器锁确实存在,因为操作同一块数据多线程不干扰,每个线程都对num加1了
# 2、看后面的执行时间可以看出,GIL锁只针对访问同一块数据的时候是串行,
#    sleep(2)等不涉及操作同一块数据的,还是并行的

猜你喜欢

转载自www.cnblogs.com/staff/p/9657370.html