版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/monkeysheep1234/article/details/84381533
解决多线程之间数据完整性和状态同步的最简单方法自然就是加锁。
GIL的全名,Global Interpreter Lock
。
解释:这个锁就是用来为了解决Cpython多线程中线程不安全问题引入的一个全局排它锁,它的作用就是在多线程情况下,保护共享资源,为了不让多个线程同时操作共享资源,导致不可预期的结果而加上的锁,在一个线程操作共享资源时,其他线程请求该资源,只能等待GIL解锁。这个设置在Cpython刚引入多线程概念的时候就有了,然后后续的各种包和组件开发都不可避免的受到了GIL的影响,所以有人会说,python在多线程处理的时候很慢。
照此理解,参看以下代码:
#-*-coding:utf-8-*-
total =0
def add():
global total
for i in range(1000000):
total += 1
def desc():
global total
for i in range(1000000):
total -= 1
import threading
thread1 = threading.Thread(target=add)
thread2 = threading.Thread(target=desc)
thread1.start()
thread2.start()
print(total)
输出结果不为定值0,每次执行结果均不一致。
出现这种问题的原因是什么呢?
python的gil锁的释放
python中的一个线程对应于c语言中的一个线程,gil使得同一时刻只有一个线程在一个cpu上执行,无法将多个线程映射到多个cpu上执行;为解决这种不能充分利用cpu性能的问题,gil会有释放的机制,根据执行的字节码行数以及时间片段会释放gil,在遇到io操作时也会主动释放。
#-*-coding:utf-8-*-
total =0
def add():
global total
for i in range(1000000):
total += 1
def desc():
global total
for i in range(1000000):
total -= 1
import threading
thread1 = threading.Thread(target=add)
thread2 = threading.Thread(target=desc)
thread1.start()
thread1.join()
thread2.start()
thread2.join()
print(total)
此时输出结果为:0
因为:thread.join()会检验线程池中的线程是否结束,没有结束就阻塞直到线程结束,如果结束则跳转执行下一个线程的join函数。