您的位置:首页 > 编程语言 > Python开发

python 线程池ThreadPoolExecutor(上)(38)

2020-01-03 20:56 1266 查看

在前面的文章中我们已经介绍了很多关于python线程相关的知识点,比如 线程互斥锁Lock / 线程事件Event / 线程条件变量Condition 等等,而今天给大家讲解的是 线程池ThreadPoolExecutor,可能很多小伙伴会疑惑,threading 模块能创建线程,ThreadPoolExecutor 也能创建线程,两者都有什么区别呢?

众所周知,程序中使用线程会提高运行效率,虽然线程是计算机的最小单位,但是线程的创建和使用一样会占用计算机资源和产生开销,一旦创建成千上万的线程,计算机一样会死机!一个合理的程序永远都是以消耗最少的资源干最多的事,就像公司老板,永远都想以最少的钱,招最少的人,干最多的事!

 

哪个二货在背后说我

一.线程池原理

大家都使用过迅雷下载,当同时下载1000个任务甚至更多的时候,就算开通vip同时下载的数量也只有8个。如果同时创建1000个线程,首先对计算器的开销也很大,而且每次只运行8个线程,需要不停的创建和销毁,这样会显得很麻烦。

而使用线程池ThreadPoolExecutor就可以解决上面的问题,其实只需要8个线程就行了,每个线程各分配一个任务,剩下的任务排队等待,当某个线程完成了任务的时候,排队任务就可以安排给这个线程继续执行,这就是所谓的线程池ThreadPoolExecutor原理!

 

二.线程池ThreadPoolExecutor函数介绍

1.ThreadPoolExecutor构造实例的时候,传入max_workers参数来设置线程池中最多能同时运行的线程数目。

2.使用submit函数来提交线程需要执行的任务(函数名和参数)到线程池中,并返回该任务的句柄(类似于文件、画图),注意submit()不是阻塞的,而是立即返回。

3.通过submit函数返回的任务句柄,能够使用done()方法判断该任务是否结束。下面的例子可以看出,由于任务有2s的延时,在task1提交后立刻判断,task1还未完成,而在延时4s之后判断,task1就完成了。

4.使用cancel()方法可以取消提交的任务,如果任务已经在线程池中运行了,就取消不了。这个例子中,线程池的大小设置为2,任务已经在运行了,所以取消失败。如果改变线程池的大小为1,那么先提交的是task1,task2还在排队等候,这是时候就可以成功取消。

5.使用result()方法可以获取任务的返回值,注意:这个方法是阻塞的。

 

三.线程池ThreadPoolExecutor简单使用


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

# !usr/bin/env python

# -*- coding:utf-8 _*-

"""

@Author:何以解忧

@Blog(个人博客地址): shuopython.com

@WeChat Official Account(微信公众号):猿说python

@Github:www.github.com

 

@File:python_threadpool.py

@Time:2019/11/29 1queue5:25

 

@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!

"""

 

from concurrent.futures import ThreadPoolExecutor

import time

 

# 参数times用来模拟下载的时间

def down_video(times):

    time.sleep(times)

    print("down video {}s finished".format(times))

    return times

 

executor = ThreadPoolExecutor(max_workers=2)

# 通过submit函数提交执行的函数到线程池中,submit函数立即返回,不阻塞

task1 = executor.submit(down_video, (3))

task2 = executor.submit(down_video, (2))

# done方法用于判定某个任务是否完成

print("任务1是否已经完成:",task1.done())

# cancel方法用于取消某个任务,该任务没有放入线程池中才能取消成功

print("取消任务2:",task2.cancel())

time.sleep(4)

print("任务1是否已经完成:",task1.done())

# result方法可以获取task的执行结果

print(task1.result())

输出结果:

1

2

3

4

5

6

任务1是否已经完成: False

取消任务2: False

down video 2s finished

down video 3s finished

任务1是否已经完成: True

3

 

线程池的使用远不止如此,由于篇幅有限,关于线程池as_completed / map / wait 函数等我们留到下一篇文章继续介绍~~~

 

关于线程池的阻塞和执行顺序相关介绍请参考:python 线程池ThreadPoolExecutor(下)

 

 

 

猜你喜欢:

1.python线程队列Queue-FIFO

2.python线程队列LifoQueue-LIFO

3.python线程队列PriorityQueue-优先队列

4.python线程的创建和参数传递

5.python线程互斥锁Lock

6.python线程事件Event

 

转载请注明:猿说Python » python线程池ThreadPoolExecutor(上)


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: