這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)什么是Python中的線程池,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

站在用戶的角度思考問題,與客戶深入溝通,找到原陽網(wǎng)站設(shè)計與原陽網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:網(wǎng)站設(shè)計制作、做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣、申請域名、網(wǎng)絡(luò)空間、企業(yè)郵箱。業(yè)務(wù)覆蓋原陽地區(qū)。
線程池
傳統(tǒng)多線程問題?
傳統(tǒng)多線程方案會使用“即時創(chuàng)建, 即時銷毀”的策略。盡管與創(chuàng)建進(jìn)程相比,創(chuàng)建線程的時間已經(jīng)大大的縮短,但是如果提交給線程的任務(wù)是執(zhí)行時間較短,而且執(zhí)行次數(shù)極其頻繁,那么服務(wù)器將處于不停的創(chuàng)建線程,銷毀線程的狀態(tài)。
一個線程的運行時間可以分為3部分:線程的啟動時間、線程體的運行時間和線程的銷毀時間。在多線程處理的情景中,如果線程不能被重用,就意味著每次創(chuàng)建都需要經(jīng)過啟動、銷毀和運行3個過程。這必然會增加系統(tǒng)相應(yīng)的時間,降低了效率。
有沒有一種高效的解決方案呢? —— 線程池
線程池基本原理:
我們把任務(wù)放進(jìn)隊列中去,然后開N個線程,每個線程都去隊列中取一個任務(wù),執(zhí)行完了之后告訴系統(tǒng)說我執(zhí)行完了,然后接著去隊列中取下一個任務(wù),直至隊列中所有任務(wù)取空,退出線程。
使用線程池:
由于線程預(yù)先被創(chuàng)建并放入線程池中,同時處理完當(dāng)前任務(wù)之后并不銷毀而是被安排處理下一個任務(wù),因此能夠避免多次創(chuàng)建線程,從而節(jié)省線程創(chuàng)建和銷毀的開銷,能帶來更好的性能和系統(tǒng)穩(wěn)定性。
線程池要設(shè)置為多少?
服務(wù)器CPU核數(shù)有限,能夠同時并發(fā)的線程數(shù)有限,并不是開得越多越好,以及線程切換是有開銷的,如果線程切換過于頻繁,反而會使性能降低。
線程執(zhí)行過程中,計算時間分為兩部分:
1.CPU計算,占用CPU。
2.不需要CPU計算,不占用CPU,等待IO返回,比如recv(), accept(), sleep()等操作,具體操作就是比如:訪問cache、RPC調(diào)用下游service、訪問DB,等需要網(wǎng)絡(luò)調(diào)用的操作。
那么如果計算時間占50%, 等待時間50%,那么為了利用率達(dá)到最高,可以開2個線程:
假如工作時間是2秒, CPU計算完1秒后,線程等待IO的時候需要1秒,此時CPU空閑了,這時就可以切換到另外一個線程,讓CPU工作1秒后,線程等待IO需要1秒,此時CPU又可以切回去,第一個線程這時剛好完成了1秒的IO等待,可以讓CPU繼續(xù)工作,就這樣循環(huán)的在兩個線程之前切換操作。
那么如果計算時間占20%, 等待時間80%,那么為了利用率達(dá)到最高,可以開5個線程:
可以想象成完成任務(wù)需要5秒,CPU占用1秒,等待時間4秒,CPU在線程等待時,可以同時再激活4個線程,這樣就把CPU和IO等待時間,最大化的重疊起來。
抽象一下,計算線程數(shù)設(shè)置的公式就是:
N核服務(wù)器,通過執(zhí)行業(yè)務(wù)的單線程分析出本地計算時間為x,等待時間為y,則工作線程數(shù)(線程池線程數(shù))設(shè)置為 N*(x+y)/x,能讓CPU的利用率最大化。
由于有GIL的影響,python只能使用到1個核,所以這里設(shè)置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))) # 任務(wù)入隊,Queue內(nèi)部實現(xiàn)了同步機制
"""
等待所有線程運行完畢
"""
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):
# 死循環(huán),從而讓創(chuàng)建的線程在一定條件下關(guān)閉退出
while True:
try:
do, args = self.work_queue.get(block=False) # 任務(wù)異步出隊,Queue內(nèi)部實現(xiàn)了同步機制
do(args)
self.work_queue.task_done() # 通知系統(tǒng)任務(wù)完成
except:
break
# 具體要做的任務(wù)
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中的線程池了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
網(wǎng)頁標(biāo)題:什么是Python中的線程池
文章源于:http://www.chinadenli.net/article46/iphceg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機、電子商務(wù)、域名注冊、網(wǎng)站設(shè)計公司、響應(yīng)式網(wǎng)站、商城網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)