GIL全局解释器锁
python解释器有很多种,最常见的就是CPython解释器
GIL本质也是一把互斥锁:将并发变成串行牺牲效率保证数据的安全
用来阻止用一进程地下的多线程的同时执行(同一进程内多个线程无法实现并行但是可以实现并发)
GIL的存在是因为CPython解释器的内存管理不是线程安全的
垃圾回收机制:引用计数,标记清除,分代回收
研究python的多线程是否有用需要分情况谈论
比如我们要开四个任务,都是计算密集型的,每个需要用时10s
在单核情况下,开线程比开进程更节省资源
在多核情况下,开进程比开线程更节省资源,比如开进程需要10s,而开线程需要40s。
# 计算密集型 在多核情况下,开线程比开线程更节省时间资源 from multiprocessing import Process from threading import Thread import os,time def work(): res = 0 for i in range(100000000): res *= i if __name__ == '__main__': l = [] print(os.cpu_count()) start = time.time() for i in range(4): p = Process(target=work) # run time is 24.919609785079956 # p = Thread(target=work) # run time is 53.27436089515686 l.append(p) p.start() for p in l: p.join() stop = time.time() print(f"run time is {stop-start}")
# 计算IO密集型 在多核情况下,开线程要比开进程更节省时间资源 from multiprocessing import Process from threading import Thread import threading import os,time def work(): time.sleep(2) if __name__ == '__main__': l = [] print(os.cpu_count()) start = time.time() for i in range(40): # p = Process(target=work) # run is 11.970486640930176 p = Thread(target=work) # run is 2.0098724365234375 l.append(p) p.start() for p in l: p.join() stop = time.time() print(f'run is {stop-start}')
Python的多线程到底有没有用,需要看情况而定,并且肯定是有用的。
一般都是多进程+多线程配合使用。
GIL与普通的互斥锁
在多个资源抢占同一个资源时,有GIL锁的存在让同一个进程下的多个线程无法同时执行。即只有一个线程能够抢到锁,其他的要等到锁释放之后才可以抢,保证了数据的安全。
from threading import Thread import time n = 100 def task(): global n tmp = n # time.sleep(1) # 0 time.sleep(1) # 在睡眠一秒后,只有一个线程抢到 n = tmp - 1 t_list = [] for i in range(100): t = Thread(target=task) t.start() t_list.append(t) for t in t_list: t.join() print(n) # 99