21.线程,全局解释器锁(GIL)
import time from threading import Thread from multiprocessing import Process #计数的方式消耗系统资源 def two_hundred_million(): start_time = time.time() i = 0 for _ in range(200000000): i = i +1 end_time = time.time() print("Total time:{}".format(end_time-start_time)) def one_hundred_million(): start_time = time.time() i = 0 for _ in range(100000000): i = i +1 end_time = time.time() print("Total time:{}".format(end_time-start_time)) if __name__ == "__main__": #单线程--主线程 # two_hundred_million()#Total time:15.068861722946167 #多线程 # for _ in range(2): # t = Thread(target=one_hundred_million) # t.start() #Total time:16.740957498550415 #Total time:16.911967515945435 #使用多进程避免GIL的影响 ''' multiprocess库的出现在很大程度是为了弥补thread库, 因为GIL而低效率的缺陷,它完整的复制了一套thread提供的接口 方便迁移,唯一的不同就是它使用了多进程而不是多线程,每个进程有自己独立的GIL 因此不会出现进程之间的GIL争抢问题 ''' #多进程 for _ in range(2): p = Process(target=one_hundred_million) p.start() #Total time:9.545545816421509 #Total time:9.60754942893982 #注意 ''' 多进程的引入会增加程序实现时线程间数据通讯和同步的困难 计数器: 如果我们要使用多个线程累加同一变量,声明global变量,用thread.Lock() thread.release()包住全局变量.多进程不能使用同一个全局变量,只能通过 Queue队列,put和get的方法来共享数据通讯. 这就会产生额外的成本,使编程变得更加复杂 ''' #1.线程不常用,原因是底层有全局解释器锁 ''' python代码是由python虚拟机执行,(又叫解释器主循环),进行控制. python在设计的时候是这样考虑的,在主循环中同时只能由一个控制线程在执行 就像单核CPU系统中的多进程一样,内存中可以有许多程序,但是在任意给定时刻, 只能有一个程序在运行.同理,尽管python解释器中可以运行多个线程,但是 在任意的给定时刻只有一个线程会被解释器执行 对python虚拟机的访问是由全局解释器锁(GIL)控制,这个锁就是用来保证 同时只能有一个线程在运行. '''