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