中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

什么是Python中的線程池

發布時間:2020-08-25 15:41:23 來源:億速云 閱讀:157 作者:Leah 欄目:編程語言

這期內容當中小編將會給大家帶來有關什么是Python中的線程池,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

線程池

傳統多線程問題?

傳統多線程方案會使用“即時創建, 即時銷毀”的策略。盡管與創建進程相比,創建線程的時間已經大大的縮短,但是如果提交給線程的任務是執行時間較短,而且執行次數極其頻繁,那么服務器將處于不停的創建線程,銷毀線程的狀態。

一個線程的運行時間可以分為3部分:線程的啟動時間、線程體的運行時間和線程的銷毀時間。在多線程處理的情景中,如果線程不能被重用,就意味著每次創建都需要經過啟動、銷毀和運行3個過程。這必然會增加系統相應的時間,降低了效率。

有沒有一種高效的解決方案呢? —— 線程池

線程池基本原理:

我們把任務放進隊列中去,然后開N個線程,每個線程都去隊列中取一個任務,執行完了之后告訴系統說我執行完了,然后接著去隊列中取下一個任務,直至隊列中所有任務取空,退出線程。

使用線程池:

由于線程預先被創建并放入線程池中,同時處理完當前任務之后并不銷毀而是被安排處理下一個任務,因此能夠避免多次創建線程,從而節省線程創建和銷毀的開銷,能帶來更好的性能和系統穩定性。

線程池要設置為多少?

服務器CPU核數有限,能夠同時并發的線程數有限,并不是開得越多越好,以及線程切換是有開銷的,如果線程切換過于頻繁,反而會使性能降低。

線程執行過程中,計算時間分為兩部分:

1.CPU計算,占用CPU。

2.不需要CPU計算,不占用CPU,等待IO返回,比如recv(), accept(), sleep()等操作,具體操作就是比如:訪問cache、RPC調用下游service、訪問DB,等需要網絡調用的操作。

那么如果計算時間占50%, 等待時間50%,那么為了利用率達到最高,可以開2個線程:

假如工作時間是2秒, CPU計算完1秒后,線程等待IO的時候需要1秒,此時CPU空閑了,這時就可以切換到另外一個線程,讓CPU工作1秒后,線程等待IO需要1秒,此時CPU又可以切回去,第一個線程這時剛好完成了1秒的IO等待,可以讓CPU繼續工作,就這樣循環的在兩個線程之前切換操作。

那么如果計算時間占20%, 等待時間80%,那么為了利用率達到最高,可以開5個線程:

可以想象成完成任務需要5秒,CPU占用1秒,等待時間4秒,CPU在線程等待時,可以同時再激活4個線程,這樣就把CPU和IO等待時間,最大化的重疊起來。

抽象一下,計算線程數設置的公式就是:

N核服務器,通過執行業務的單線程分析出本地計算時間為x,等待時間為y,則工作線程數(線程池線程數)設置為 N*(x+y)/x,能讓CPU的利用率最大化。

由于有GIL的影響,python只能使用到1個核,所以這里設置N=1。

    import queue
    import threading
    import time
    
    
    class WorkManager(object):
       def __init__(self, work_num=1000, thread_num=2):
          self.work_queue = queue.Queue()
          self.threads = []
          self.__init_work_queue(work_num)
          self.__init_thread_pool(thread_num)
    
       """
          初始化線程
       """
    
       def __init_thread_pool(self, thread_num):
          for i in range(thread_num):
             self.threads.append(Work(self.work_queue))
    
    
       """
          初始化工作隊列
       """
    
       def __init_work_queue(self, jobs_num):
          for i in range(jobs_num):
             self.add_job(do_job, i)
    
       """
          添加一項工作入隊
       """
    
       def add_job(self, func, *args):
          self.work_queue.put((func, list(args)))  # 任務入隊,Queue內部實現了同步機制
    
       """
          等待所有線程運行完畢
       """
    
       def wait_allcomplete(self):
          for item in self.threads:
             if item.isAlive(): item.join()
    
    
    class Work(threading.Thread):
       def __init__(self, work_queue):
          threading.Thread.__init__(self)
          self.work_queue = work_queue
          self.start()
    
       def run(self):
          # 死循環,從而讓創建的線程在一定條件下關閉退出
          while True:
             try:
                do, args = self.work_queue.get(block=False)  # 任務異步出隊,Queue內部實現了同步機制
                do(args)
                self.work_queue.task_done()  # 通知系統任務完成
             except:
                break
    
             # 具體要做的任務
    
    
    def do_job(args):
       time.sleep(0.1)  # 模擬處理時間
       print(threading.current_thread())
       print(list(args))
    
    
    if __name__ == '__main__':
       start = time.time()
       work_manager = WorkManager(100, 10)  # 或者work_manager =  WorkManager(10000, 20)
       work_manager.wait_allcomplete()
       end = time.time()
       print("cost all time: %s" % (end - start))

上述就是小編為大家分享的什么是Python中的線程池了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

淅川县| 边坝县| 晴隆县| 龙陵县| 宁都县| 丽江市| 怀来县| 阿巴嘎旗| 诸城市| 乐至县| 沐川县| 诏安县| 嘉荫县| 沽源县| 海兴县| 腾冲县| 青岛市| 开封县| 灵武市| 巩义市| 双江| 封丘县| 华阴市| 呼玛县| 商水县| 台湾省| 界首市| 仁寿县| 永善县| 宁夏| 河津市| 沙坪坝区| 绥德县| 北辰区| 康保县| 包头市| 长岛县| 利川市| 花垣县| 贵州省| 南安市|