从开始学习Python的时候,就一直听大家说Python的效率比较低,不能实现真正的多线程,只是异步并发,但是,Python 并不是没有多线程,那么今天就基于Python的多线程聊聊线程池。
线程
聊线程就不得不聊一下进程,进程是程序的一次运行,在进程运行的过程当中,并不一定是一个任务执行到底,可能有多个子任务,那这些任务就可能是线程了,线程,又被叫做轻量级进程,是一个进程当中的一部分,没有独立的内存空间,进程下的线程共享进程的内存空间,所以,线程之间进行通信的成本要低于进程间的通信。线程从创建,通信和切换成本都要低于进程,所以,基于开销(虚拟内存,栈,全局变量,用户空间,内核堆栈,寄存器)考虑的话,多线程要优于多进程(这里要注意的是,实际场景除了开销之外还需要考虑性能)。
Python 多线程
因为Python 为了保证在单CPU状态下,同时只有一个线程运行并且不被抢占,使用了全局解释器锁(GIL)机制,所以,Python的多线程实际上是异步并发,就是将多个任务切分位时间片,在一个任务的时间片执行到阻塞状态的时候,切换执行另外一个任务的时间片,降低阻塞带来的无效等待,提高代码的执行效率,所以Python多线程对计算型项目并没有很大的效率提升。
任务顺序执行:
任务异步并发执行:
Python 内置了thread 和 threading模块供开发者进行多线程开发,实际开发当中,大家使用threading模块更多一点,至于他二者的区别,我们之后再聊,这里提供一个简单的案例:
import threading
from time import sleep
#线程任务
def task(task_number,run_time):
"""
task_number 任务编号
run_time 使用sleep模拟运行时间
"""
print("%s task is running"%task_number)
sleep(run_time)
print("%s task is end"%task_number)
def main():
tasks = [3,4,1,2,6] #任务执行的时间池
task_list = []
for index,run_time in enumerate(tasks):
t = threading.Thread(target=add, args=(index, run_time)) #创建线程
task_list.append(t)
for t in task_list:
t.start() #线程启动
for t in task_list:
t.join() #线程挂起
if __name__ == "__main__":
main()
线程池
线程开销很小,但是假如任务很多的情况下,如果每个任务都创建一个线程,执行完成销毁线程,然后再次创建,销毁,实际上还是有很大的损耗,那么可不可以不销毁,线程执行完任务之后存放到一个队列当中,等待下次任务再次执行,这样就可以避免不断创建和销毁带来的资源损耗了(有点像公交车,执行完任务,返回运输点等待下次任务),这种策略就是线程池。
作为一款开发高效的语言,Python依然提供了线程池的功能模块,还是以一个基础的案例来看:
from concurrent.futures import ThreadPoolExecutor
import threading
import time
# 线程任务
def task(max):
my_sum = 0
for i in range(max):
# threading.current_thread 调用者控制的threading.Thread线程对象。
# 如果当前调用者控制的线程不是通过threading.Thread创建的,
# 则返回一个功能受限的虚拟线程对象。
print(threading.current_thread().name + ' ' + str(i))
my_sum += i
return my_sum
# 创建线程池,max_workers是线程池线程个数,我们以5位例
pool = ThreadPoolExecutor(max_workers=5)
# 向线程池提交一个task, 后面是线程的参数
task1 = pool.submit(task, 21)
# done返回线程是否结束
print(task1.done())
# 查看task1代表的任务返回的结果
print(task1.result())
# 关闭线程池
pool.shutdown()
对比多线程的案例,可以看出,这个案例并没有创建线程,而是使用submit方法对线程池提交任务,然后查看任务的状态和结果,在线程池关闭之前也没有销毁线程。
关于Python线程池我们先初步了解到这里,之后再对Python线程池实现进行分析,最后还请各位大佬多多指点。