婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > Python線程池的正確使用方法

Python線程池的正確使用方法

熱門標簽:企業微信地圖標注 銀川電話機器人電話 高德地圖標注收入咋樣 B52系統電梯外呼顯示E7 鶴壁手機自動外呼系統違法嗎 萊蕪電信外呼系統 沈陽防封電銷電話卡 怎么辦理400客服電話 地圖標注多個

Python線程池的正確使用

1、為什么要使用線程池呢?

因為線程執行完任務之后就會被系統銷毀,下次再執行任務的時候再進行創建。這種方式在邏輯上沒有啥問題。但是系統啟動一個新線程的成本是比較高,因為其中涉及與操作系統的交互,操作系統需要給新線程分配資源。打個比方吧!就像軟件公司招聘員工干活一樣。當有活干時,就招聘一個外包人員干活。當活干完之后就把這個人員辭退掉。你說在這過程中所耗費的時間成本和溝通成本是不是很大。那么公司一般的做法是:當項目立項時就確定需要幾名開發人員,然后將這些人員配齊。然后這些人員就常駐在項目組,有活就干,沒活就摸魚。線程池也是同樣的道理。線程池可以定義最大線程數,這些線程有任務就執行任務,沒任務就進入線程池中歇著。

2、線程池怎么用呢?

線程池的基類是concurrent.futures模塊中的Executor類,而Executor類提供了兩個子類,即ThreadPoolExecutor類和ProcessPoolExecutor類。其中ThreadPoolExecutor用于創建線程池,而ProcessPoolExecutor用于創建進程池。本文將重點介紹ThreadPoolExecutor類的使用。首先,讓我們來看看ThreadPoolExecutor類的構造函數。這里使用的Python版本是:3.6.7

      def __init__(self, max_workers=None, thread_name_prefix=''):
        """Initializes a new ThreadPoolExecutor instance.

        Args:
            max_workers: The maximum number of threads that can be used to
                execute the given calls.
            thread_name_prefix: An optional name prefix to give our threads.
        """
        if max_workers is None:
            # Use this number because ThreadPoolExecutor is often
            # used to overlap I/O instead of CPU work.
            max_workers = (os.cpu_count() or 1) * 5
        if max_workers = 0:
            raise ValueError("max_workers must be greater than 0")

        self._max_workers = max_workers
        self._work_queue = queue.Queue()
        self._threads = set()
        self._shutdown = False
        self._shutdown_lock = threading.Lock()
        self._thread_name_prefix = (thread_name_prefix or
                                    ("ThreadPoolExecutor-%d" % self._counter()))

他的構造函數只有兩個參數:一個是max_workers參數,用于指定線程池的最大線程數,如果不指定的話則默認是CPU核數的5倍。另一個參數是thread_name_prefix,它用來指定線程池中線程的名稱前綴。其他參數:

  • _shutdown初始值值為False,默認情況下線程池不銷毀,即線程池的生命周期跟項目的生命周期一致。
  • self._work_queue = queue.Queue()生成緩沖隊列。
  • _threads沒有任務被提交時,線程的數量設置為0。
  • _shutdown_lock 指定線程池的鎖是Lock鎖。
  • 說完了線程池的創建之后,接著來看看線程池中比較常用的幾個方法吧。
  • submit(self, fn, *args, **kwargs):
  • 該方法用提交任務,即將fn函數提交給線程池,*args代表傳給fn函數的參數,**kwargs代表以關鍵字參數的形式為fn函數傳入參數。
  • shutdown(self, wait=True):
  • 關閉線程池
  • map(func, *iterables, timeout=None, chunksize=1):
  • 該函數類似于全局函數map(func,*iterables),只是該函數將會啟動多個線程,以異步方式立即對iterables執行map處理。

程序將task函數通過submit方法提交給線程池之后,線程池會返回一個Future對象,該對象的作用主要是用于獲取線程任務函數的返回值。Future提供了如下幾個方法。

  • cancel():取消該Future代表的線程任務。如果該任務正在執行,不可取消,則該方法返回False;否則,程序會取消該任務,并返回True。
  • result(timeout=None):獲取該 Future 代表的線程任務最后返回的結果。如果 Future 代表的線程任務還未完成,該方法將會阻塞當前線程,其中 timeout 參數指定最多阻塞多少秒。
  • add_done_callback(fn):為該 Future 代表的線程任務注冊一個“回調函數”,當該任務成功完成時,程序會自動觸發該 fn 函數。
  • done():如果該Future代表的線程任務被成功取消或執行完成,則該方法返回True。

來個簡單的例子:

該例中創建了一個最大線程數是2的線程池來執行async_add函數。

from concurrent.futures import ThreadPoolExecutor
import threading
import time


def async_add(max):
    sum = 0
    for i in range(max):
        sum = sum + i
    time.sleep(1)
    print(threading.current_thread().name + "執行求和操作求得的和是=" + str(sum))
    return sum

# 創建兩個線程
pool = ThreadPoolExecutor(max_workers=2, thread_name_prefix='測試線程')
# 向線程池提交一個task,20作為async_add()函數的參數
future1 = pool.submit(async_add, 20)
# 向線程池再提交一個task
future2 = pool.submit(async_add, 50)
# 判斷future1代表的任務是否執行完
time.sleep(2)
print(future1.done())
print(future2.done())
# 查看future1代表的任務返回的結果
print('線程一的執行結果是=' + str(future1.result()))
# 查看future2代表的任務的返回結果
print('線程二的執行結果是=' + str(future2.result()))
print("----" + threading.current_thread().name + "----主線程執行結束-----")

運行結果是:

測試線程_0執行求和操作求得的和是=190
測試線程_1執行求和操作求得的和是=1225
True
True
線程一的執行結果是=190
線程二的執行結果是=1225
----MainThread----主線程執行結束-----

本例中定義了一個最大線程數是2的線程池,并向線程池中提交了兩個任務,其中async_add函數就是要執行的任務。在async_add函數中添加 time.sleep(1) 休眠一秒是為了驗證done()方法返回的結果。最后才打印主線程執行結束表明result()方法是阻塞的。如果將result()屏蔽掉。
改成如下形式:

# 創建兩個線程
pool = ThreadPoolExecutor(max_workers=2, thread_name_prefix='測試線程')
# 向線程池提交一個task,20作為async_add()函數的參數
future1 = pool.submit(async_add, 20)
# 向線程池再提交一個task
future2 = pool.submit(async_add, 50)
# 判斷future1代表的任務是否執行完
print(future1.done())
print(future2.done())
print("----" + threading.current_thread().name + "----主線程執行結束-----")

則運行結果是:

False
False
----MainThread----主線程執行結束-----
測試線程_0執行求和操作求得的和是=190
測試線程_1執行求和操作求得的和是=1225

3、如何非阻塞的獲取線程執行的結果

前面介紹的result()方法是通過阻塞的方式來獲取線程的運行結果的。那么如果通過非阻塞的方法來獲取線程任務最后的返回結果呢?這里就需要使用線程的回調函數來獲取線程的返回結果。

from concurrent.futures import ThreadPoolExecutor
import threading
import time


def async_add(max):
    sum = 0
    for i in range(max):
        sum = sum + i
    time.sleep(1)
    print(threading.current_thread().name + "執行求和操作求得的和是=" + str(sum))
    return sum


with ThreadPoolExecutor(max_workers=2) as pool:
    # 向線程池提交一個task
    future1 = pool.submit(async_add, 20)
    future2 = pool.submit(async_add, 50)


    # 定義獲取結果的函數
    def get_result(future):
        print(threading.current_thread().name + '運行結果:' + str(future.result()))


    # 查看future1代表的任務返回的結果
    future1.add_done_callback(get_result)
    # 查看future2代表的任務的返回結果
    future2.add_done_callback(get_result)
    print('------------主線程執行結束----')

運行結果是:

------------主線程執行結束----
ThreadPoolExecutor-0_1執行求和操作求得的和是=1225
ThreadPoolExecutor-0_1運行結果:1225
ThreadPoolExecutor-0_0執行求和操作求得的和是=190
ThreadPoolExecutor-0_0運行結果:190

從結果可以看出獲取線程執行結果的方法完全沒有阻塞到主線程的運行。這里通過add_done_callback函數向線程池中注冊了一個獲取線程執行結果的函數get_result。
由于線程池實現了上下文管理協議(Context Manage Protocol),因此程序可以使用with語句來管理線程池,這樣即可避免手動關閉線程池。

4、線程池的運行策略

這里有必要介紹一下線程池的執行策略,也就是說當線程池中的任務數大于線程池的最大線程數時,線程池該如何處理這些任務呢?處理不了的任務是直接丟棄還是慢慢處理呢?再回答這個問題之前,讓我們來看下下面這個例子:這里定義了一個最大線程數是4個線程池,然后向線程池中提交了100個task任務。

def async_add(max):
    sum = 0
    for i in range(max):
        sum = sum + i
    time.sleep(1)
    print(threading.current_thread().name + "執行求和操作求得的和是=" + str(sum))
    return sum


with ThreadPoolExecutor(max_workers=4) as pool:
    for i in range(100):
        pool.submit(async_add, i)
    print('------------主線程執行結束----')

運行結果是:

------------主線程執行結束----
ThreadPoolExecutor-0_1執行求和操作求得的和是=0
ThreadPoolExecutor-0_0執行求和操作求得的和是=0
ThreadPoolExecutor-0_3執行求和操作求得的和是=3
ThreadPoolExecutor-0_2執行求和操作求得的和是=1
...省略部分結果.....
ThreadPoolExecutor-0_1執行求和操作求得的和是=4656
ThreadPoolExecutor-0_2執行求和操作求得的和是=4753
ThreadPoolExecutor-0_0執行求和操作求得的和是=4560
ThreadPoolExecutor-0_3執行求和操作求得的和是=4851

從運行結果可以看出:一直都是相同的線程來執行這些任務,并且所有的任務都沒有被丟棄。并且任務按照先來后到的順序來執行。這里就需要說到線程池默認的緩沖隊列了。self._work_queue = queue.Queue() 該語句會創建一個大小無限制的緩沖隊列。該隊列是一個 FIFO(先進先出)的常規隊列。所以當任務數超過最大線程數時,任務會暫時放在緩沖隊列queue中。當線程空閑之后會從緩沖隊列中取出任務來執行。
該隊列有個參數maxsize可以限制隊列的大小。如果隊列的大小達到隊列的上限,就會加鎖,再次加入元素時,就會被阻塞,直到隊列中的元素被消費。如果將maxsize的設置為0或者負數時,則該隊列的大小就是無限制的。

到此這篇關于Python線程池的正確使用方法的文章就介紹到這了,更多相關Python線程池的正確使用內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • Python 線程池模塊之多線程操作代碼
  • Python爬蟲之線程池的使用
  • python線程池的四種好處總結
  • python爬蟲線程池案例詳解(梨視頻短視頻爬取)
  • python線程池 ThreadPoolExecutor 的用法示例
  • 實例代碼講解Python 線程池
  • Python 如何創建一個線程池
  • python線程池如何使用
  • 解決python ThreadPoolExecutor 線程池中的異常捕獲問題
  • Python定時器線程池原理詳解
  • Python 使用threading+Queue實現線程池示例

標簽:安慶 湘西 銀川 葫蘆島 三亞 呼倫貝爾 烏魯木齊 呼倫貝爾

巨人網絡通訊聲明:本文標題《Python線程池的正確使用方法》,本文關鍵詞  Python,線程,池,的,正確,使用方法,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Python線程池的正確使用方法》相關的同類信息!
  • 本頁收集關于Python線程池的正確使用方法的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    久久综合色8888| 日韩欧美一二区| 色狠狠一区二区| 久久久蜜桃精品| 国产伦理精品不卡| 亚洲精品在线观| 国产激情一区二区三区四区 | 日韩高清在线观看| 欧美亚男人的天堂| 丝袜诱惑制服诱惑色一区在线观看| 欧美日韩综合色| 蜜桃av噜噜一区二区三区小说| 欧美大片国产精品| 国产99久久精品| 1024成人网| 欧美日韩国产中文| 国产激情视频一区二区三区欧美| 国产嫩草影院久久久久| 国产麻豆精品在线| 久久女同性恋中文字幕| 国产老女人精品毛片久久| 欧美一二三四在线| 亚洲成人中文在线| 午夜视频久久久久久| 欧美一区二区久久| 亚洲v中文字幕| 五月天中文字幕一区二区| 91美女片黄在线观看91美女| 午夜精品爽啪视频| 久久久久99精品一区| 91视频观看免费| 蜜臀久久99精品久久久久宅男| 亚洲精品在线电影| 欧美亚洲综合网| 丁香婷婷综合五月| 午夜私人影院久久久久| 中文在线一区二区| 欧美成人精品福利| 色天天综合色天天久久| 国产麻豆精品theporn| 偷拍与自拍一区| 亚洲欧美偷拍三级| 久久久精品综合| 4438x成人网最大色成网站| 91亚洲精品乱码久久久久久蜜桃| 美女性感视频久久| 亚洲图片有声小说| 亚洲欧美综合另类在线卡通| 久久精品视频一区二区| 欧美色老头old∨ideo| 日韩欧美国产综合在线一区二区三区| 国产成人免费在线| 美女视频黄久久| 日本成人在线不卡视频| 天天av天天翘天天综合网 | 91精品久久久久久蜜臀| 91久久奴性调教| 91在线播放网址| 成人av午夜影院| 波多野结衣欧美| 北岛玲一区二区三区四区 | 国产精一品亚洲二区在线视频| 亚洲精品免费一二三区| 亚洲精品成人少妇| 亚洲人一二三区| 亚洲你懂的在线视频| 亚洲欧美区自拍先锋| 伊人性伊人情综合网| 亚洲第一激情av| 日韩国产欧美在线观看| 日本中文字幕不卡| 久久激情综合网| 成人综合婷婷国产精品久久免费| 午夜精品影院在线观看| 亚洲成人av资源| 日韩国产欧美在线观看| 日日夜夜一区二区| 九色|91porny| 福利一区二区在线| 99久久国产综合精品女不卡| 成人av动漫在线| 色狠狠桃花综合| 色婷婷av一区二区三区之一色屋| 欧美亚洲国产一区在线观看网站| 欧美三级资源在线| 精品国产乱码久久久久久闺蜜 | 毛片av一区二区| 国产一区二区三区在线观看免费 | 一区二区在线免费观看| 日本一区二区三区四区在线视频| 久久综合九色综合欧美亚洲| 国产视频一区二区在线| 亚洲精品v日韩精品| 美女免费视频一区| 97久久精品人人做人人爽 | 亚洲精品成a人| 亚洲在线成人精品| 国产在线精品一区二区不卡了| 99精品视频在线观看免费| 这里只有精品免费| 成人欧美一区二区三区| 亚洲mv在线观看| 国产一区不卡视频| 欧美日韩国产另类一区| 精品免费日韩av| 亚洲国产视频一区| 国产aⅴ综合色| 88在线观看91蜜桃国自产| 国产三级欧美三级日产三级99| 亚洲欧洲一区二区三区| 日韩精品乱码免费| 91欧美激情一区二区三区成人| 日韩精品影音先锋| 亚洲少妇中出一区| 美女网站在线免费欧美精品| 欧美系列亚洲系列| 中文字幕的久久| 精东粉嫩av免费一区二区三区| 欧美影视一区在线| 综合久久久久久| 99久久免费精品| 欧美—级在线免费片| 国产一区二区久久| 精品福利一二区| 免播放器亚洲一区| 欧美色视频在线观看| 一区二区三区四区在线| 91网址在线看| 亚洲男同1069视频| 色婷婷激情一区二区三区| 综合精品久久久| 91伊人久久大香线蕉| 亚洲久本草在线中文字幕| 99久久婷婷国产综合精品| 国产精品不卡在线观看| 丰满少妇久久久久久久| 欧美激情一二三区| 风间由美一区二区av101| 欧美国产视频在线| 白白色 亚洲乱淫| 国产精品入口麻豆原神| 国产suv一区二区三区88区| 日韩欧美在线影院| 美女视频免费一区| 国产亚洲欧美色| 不卡av电影在线播放| 亚洲男同1069视频| 欧美亚洲动漫制服丝袜| 婷婷久久综合九色综合绿巨人| 欧美日韩卡一卡二| 九九视频精品免费| 一色屋精品亚洲香蕉网站| 色综合久久久久综合体桃花网| 亚洲一区在线视频观看| 欧美一区二区三区四区高清| 狠狠色丁香九九婷婷综合五月| 久久综合久久鬼色中文字| 国产aⅴ精品一区二区三区色成熟| 国产精品系列在线| 欧美午夜片在线看| 激情av综合网| 亚洲婷婷综合色高清在线| 欧美男同性恋视频网站| 国产在线国偷精品产拍免费yy| 国产精品色眯眯| 欧美日韩aaaaaa| 国产精品一区免费在线观看| 欧美国产日韩亚洲一区| 欧美日韩视频专区在线播放| 精品夜夜嗨av一区二区三区| 综合av第一页| 久久伊人蜜桃av一区二区| 色香蕉成人二区免费| 奇米精品一区二区三区在线观看| 国产欧美日产一区| 欧美老肥妇做.爰bbww| 国产成人av资源| 日韩国产精品久久久| 国产精品日韩精品欧美在线| 911精品国产一区二区在线| av不卡一区二区三区| 精品一区免费av| 亚洲成人免费在线观看| 国产欧美一区二区三区网站| 欧美妇女性影城| 一本高清dvd不卡在线观看| 久久99精品久久久久久| 一区二区免费看| 亚洲国产精品99久久久久久久久| 91麻豆精品91久久久久久清纯| av在线不卡网| 国产精品12区| 精品一区二区三区久久| 日韩精品视频网| 天天综合色天天综合| 亚洲男同性视频| 一区二区三区欧美亚洲| 亚洲手机成人高清视频| 久久久久97国产精华液好用吗| 日韩亚洲欧美一区|