本文来介绍下,多线程是如何工作的,多线程就一定效率就高吗,本文可以告诉你不一定。
1. 先来了解Python解释器执行代码方式
Python代码的执行由Python 虚拟机(也叫解释器主循环,CPython版本)来控制,Python 在设计之初就考虑到要在解释器的主循环中,同时只有一个线程在执行,即在任意时刻,只有一个线程在解释器中运行。对Python 虚拟机的访问由全局解释器锁(GIL)来控制,正是这个锁能保证同一时刻只有一个线程在运行。
在多线程环境中,Python 虚拟机按以下方式执行:
设置GIL->切换到一个线程去运行->运行-> 把线程设置为睡眠状态->解锁GIL-> 再次重复前面步骤
2. 什么是GIL
GIL(Global Interpreter Lock),中文翻译叫全局解释器锁。下面这张图可以描述GIL的工作原理。
解释下:
一个任务三个线程去处理,上面有5段执行任务,分别有不用线程去处理。开始线程1去执行,然后遇到了GIL,这个时候就锁住了线程1,交给线程2,线程1和线程2交接的时候,有一个读写时间,这个很短。接着线程2执行完了,锁住线程2,交给线程3,然后,锁住线程3,交给线程1,锁住线程1,交给线程3,大概就是这样一个过程。
3.举例来证明,多线程效率不一定高
2. 什么是GIL
GIL(Global Interpreter Lock),中文翻译叫全局解释器锁。下面这张图可以描述GIL的工作原理。
解释下:
一个任务三个线程去处理,上面有5段执行任务,分别有不用线程去处理。开始线程1去执行,然后遇到了GIL,这个时候就锁住了线程1,交给线程2,线程1和线程2交接的时候,有一个读写时间,这个很短。接着线程2执行完了,锁住线程2,交给线程3,然后,锁住线程3,交给线程1,锁住线程1,交给线程3,大概就是这样一个过程。
3.举例来证明,多线程效率不一定高
import threading
from queue import Queue
import copy
import time
def job(l,q):
res = sum(l)
q.put(res)
def exampleFuc(l):
q = Queue()
threads = []
for i in range(4):
t = threading.Thread(target=job, args=(copy.copy(l), q))
t.start()
threads.append(t)
[t.join() for t in threads]
total = 0
for x in range(4):
total = total + q.get()
print(total)
def normal(l):
total = sum(l)
print(total)
if __name__ == '__main__':
l = list(range(1000000))
s_t = time.time()
normal(l*4)
print('普通方法执行时间是:', time.time()-s_t)
s_t = time.time()
exampleFuc(l)
print('多线程执行时间是:', time.time()-s_t)
运行结果:
============= RESTART: C:\Users\Anthony\Desktop\thread_queue.py =============
1999998000000
普通方法执行时间是: 0.26999735832214355
1999998000000
多线程执行时间是: 0.3099970817565918
>>>
从结果可以看到,普通方法执行时间大概是0.2秒,多线程执行的时候是0.3秒,多线程效率反而更低。