In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple
native threads from executing Python bytecodes at once. This lock is necessary mainly
because CPython’s memory management is not thread-safe. (However, since the GIL
exists, other features have grown to depend on the guarantees that it enforces.)
结论: 在CPython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势
from threading import Thread, Lockimport timedefwork():global nwith lock: temp = n time.sleep(0.1) n = temp -1if__name__=='__main__': lock =Lock() n =100 li = []for i inrange(100): t =Thread(target=work) li.append(t) t.start()for t in li: t.join()print(n)# 结果肯定为0,由原来的并发执行变成串行,牺牲了执行效率保证了数据安全,不加锁则结果可能为99
from multiprocessing import Processfrom threading import Threadimport timeimport osdefwork(): res =0for i inrange(100000000): res *= iif__name__=='__main__': li = []print(os.cpu_count())# 4核 start = time.time()for i inrange(4): p =Process(target=work)# 耗时 4.45s p =Thread(target=work)# 耗时 16.35s li.append(p) p.start()for p in li: p.join() stop = time.time()print('run time is %s'% (stop - start))
如果并发的多个任务是I/O密集型:多线程效率高
from multiprocessing import Processfrom threading import Threadimport timeimport osdefwork(): time.sleep(2)print('==>')if__name__=='__main__': li = []print(os.cpu_count())# 4核 start = time.time()for i inrange(400): p =Process(target=work)# 耗时 13.34s, 大部分时间耗费在创建进程上 p =Thread(target=work)# 耗时 2.04s li.append(p) p.start()for p in li: p.join() stop = time.time()print('run time is %s'% (stop - start))