[转载]python的全局锁

转自:https://blog.csdn.net/weixin_44737199/article/details/91345161

 

python的全局锁

Queue模块

  • 提供FIFO的Queue,LIFO的队列,优先队列,虽然Queue类是线程安全的,适用于多线程间安全的交换数据,内部使用了Lock和Condition,虽然Queue类的size加了锁,但是依然不能保证立即get,put就能成功,因为读取大小和get,put方法是分开的,在一个线程在读取或者操作时,可能会被其他线程抢占了资源.

GIL全局解释器锁

  • CPython 在解释器进程级别有一把锁,叫做GIL,即全局解释器锁。
  • GIL 保证CPython进程中,只有一个线程执行字节码。甚至是在多核CPU的情况下,也只允许同时只能有一个CPU上运行该进程的一个线程。(所以,Python中的多线程都是假并行的)

CPython中

  • IO密集型,某个线程阻塞,就会调度其他就绪线程;

  • CPU密集型,当前线程可能会连续的获得GIL,导致其它线程几乎无法使用CPU。

  • 在CPython中由于有GIL存在,IO密集型,使用多线程较为合算;CPU密集型,使用多进程,要绕开GIL

  • python中绝大多数内置数据结构的读、写操作都是原子操作。

  • 由于GIL的存在,Python的内置数据类型在多线程编程的时候就变成了安全的了,但是实际上它们本身不是线程安全类型

如下测试,

#IO密集型
import threading
import datetime

start = datetime.datetime.now()
def fn(x=1000000000):
    count = 0
    while count < x:
        count += 1
    print(threading.current_thread(),count)

thrad_list=[]
for i in range(5):
    t = threading.Thread(target=fn,name='fn{}'.format(i+1))
    t.start()
    thrad_list.append(t)

for t in thrad_list:
    t.join()

delta = (datetime.datetime.now()-start).total_seconds()
print(delta)
----------------------------------------------------------------
<Thread(fn2, started 10396)> 1000000000
<Thread(fn5, started 5988)> 1000000000
<Thread(fn1, started 13688)> 1000000000
<Thread(fn4, started 2068)> 1000000000
<Thread(fn3, started 15576)> 1000000000
225.282195

 

#CPU密集型
import datetime
import threading

start = datetime.datetime.now()
def fn(name,x=100000000):
    count = 0
    while count < x:
        count += 1
    print(name,count)

for i in range(5):
    fn("{},fn{}".format(threading.current_thread(),1+1))

delta = (datetime.datetime.now()-start).total_seconds()
print(delta)

---------------------------------------------------------------
<_MainThread(MainThread, started 4648)>,fn2 1000000000
<_MainThread(MainThread, started 4648)>,fn2 1000000000
<_MainThread(MainThread, started 4648)>,fn2 1000000000
<_MainThread(MainThread, started 4648)>,fn2 1000000000
<_MainThread(MainThread, started 4648)>,fn2 1000000000
211.827783
#单线程是串行运行的

从上面两个例子看出,对于python中,CPU密集型用多线程写,跟串行没有什么区别,根本就体现不出来优势,原因搜索GIL存在.(可以使用多进程)

posted @ 2020-10-29 15:54  workingdiary  阅读(122)  评论(0编辑  收藏  举报