python GIL全局解释器锁的理解

发布时间:2026/9/7 22:43:27
python GIL全局解释器锁的理解 GIL的全称为Lock, 其意思是全局解释器锁, 这个GIL并非其特性, 它是仅在解释器里得以引入的某个概念, 而于其他语言所编写成的解释器里面就不存在这个GIL, 例如Pypy。为什么会有gil因为电脑出现多核CPU以及CPU频率得到提升因而为充分利用多核处理器多线程编程方式更加普及, 随之而来的困难是线程间数据一致性和状态同步的问题, 又因利用了多核所以避免不了这个困难存在, 为解决数据无法同步的问题故而设计了gil全局解释器锁。提及gil解释器锁, 我们常常会想到, 在多线程里来共享全局变量之际, 会存在线程会针对全局变量作出资源竞争, 会致使对全局变量的修改生成并非我们期望的状貌, 而在那个时候我们所运用的是处于线程模块当中的互斥锁, 如此一来每次针对全局变量开展操作之时, 仅有一个线程能够获取到这个全局变量瞧瞧下面的代码:importthreading global_num 0deftest1():globalglobal_numforiinrange(1000000): global_num 1print(test1,global_num)deftest2():globalglobal_numforiinrange(1000000): global_num 1print(test2,global_num) t1 threading.Thread(targettest1) t2 threading.Thread(targettest2) t1.start() t2.start()在上述的示例里, 我们构建了两个线程, 用以对相关操作进行加一竞赛, 然而最终呈现的结果, 并非是我们所期望达成的那般, 因此我们于此处增添了互斥锁。importthreadingimporttime global_num 0lock threading.Lock()deftest1():globalglobal_num lock.acquire()foriinrange(1000000): global_num 1lock.release()print(test1,global_num)deftest2():globalglobal_num lock.acquire()foriinrange(1000000): global_num 1lock.release()print(test2,global_num) t1 threading.Thread(targettest1) t2 threading.Thread(targettest2) start_time time.time() t1.start() t2.start()这一回能够获取到我们所期望的结果, 在先前我的博客文章当中曾经提及过这个问题, 在此处就不再过多啰嗦了。在解释器当中, 当咱们的代码存在一个线程着手访问解释器之际, GIL会将那个大锁锁住, 这时其他的线程就只能干巴巴地等着, 没办法对解释器的资源展开访问, 这一情况同咱们的互斥锁相仿。而仅限这个历程发生在咱们这儿, 并且也要等这个线程被分配的时间到达后, 该线程把gil释放掉, 跟咱们互斥锁的lock.()情形类似, 另外的线程才开始运转, 严格来讲, 这无疑同样是个单线程。瞅瞅下面这幅图, 仅仅是把我第一段代码里头的变量换成count, 针对此处我们不理睬互斥锁, 单单去思考gil。执行过程1.拿到全局变量count2.申请到解释器的gil3.解释器调用系统原生线程4.在cpu1上执行规定的时间5.执行的时间已然到了, 有着要求去释放gil , 等到下一次获取到gil的时候, 该程序会从这里接续着本次开启执行。6.拿到了全局变量, 这时针对全局count的操作尚未完成, 所以所拿到的以及拿到的count实际上是一样的, 像这样也就易于解释为何结果不是200万 而是少于200万。7.申请到了gil锁8.调用原生的线程9.若为单核的中央处理器, 那么便会放置于中央处理器1上去运行, 接着, 并非关键之处在于, 就如同在中央处理器3上进行运行这般。10.执行规定的时间此时完成了对count的加一操作11.此时此刻, 执行时间尚未抵达, 线程2完成了针对count的操作, 随之将count进行了加一的动作, 并且随之释放了gil锁。12.线程1又申请到了gil锁重复之前的操作。13.线程1, 对count执行操作, 数量为万, 完成操作时, 执行时间已到, 此时释放gil锁。综合上面的步骤就能很好的理解gil锁哪些情况适合用多线程呢只要当前正处于开展耗时的IO操作的时段, 能够将GIL释放掉, 因此只要是处于IO密集型的代码范围之中, 运用多线程便是颇为适宜的。哪些情况适合用多进程呢用于计算密集型比如计算某一个文件夹的大小。