python 線程池ThreadPoolExecutor(上)(38)

在前面的文章中我們已經介紹了很多關於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(上)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章