亚洲精品久久久久久第一页-人妻少妇精彩视品一区二区三区-91国产自拍免费视频-免费一级a在线播放视频正片-少妇天天日天天射天天爽-国产大屁股喷水视频在线观看-操美女骚穴抽插性爱视频-亚洲 欧美 中文字幕 丝袜-成人免费无码片在线观看

python線程池內(nèi)存耗盡 python進(jìn)程池內(nèi)存一直上漲


python線程池內(nèi)存耗盡 python進(jìn)程池內(nèi)存一直上漲

文章插圖
前言大家好,我是星期八 。
我們都知道,不管是Java,還是C++,還是Go,還是Python,都是有線程這個(gè)概念的 。
但是我們知道,線程是不能隨便創(chuàng)建的,就像每招一個(gè)員工一樣,是有代價(jià)的,無(wú)限制招人肯定最后各種崩潰 。
所以通常情況下,我們會(huì)引出線程池這個(gè)概念 。
本質(zhì)就是我就招了幾個(gè)固定的員工,給他們派活,某一個(gè)人的活干完了再去任務(wù)中心領(lǐng)取新的活 。
防止任務(wù)太多,一次性招太多工人,最后系統(tǒng)崩潰 。
開(kāi)心一刻
理想的多線程實(shí)際的多線程from concurrent.futures import …可能也是因?yàn)榫€程池這個(gè)東西用的越來(lái)越多了吧,從Python3.2+之后,就成了內(nèi)置模塊 。
對(duì)的,直接就能使用,不需要pip進(jìn)行安裝什么的 。
concurrent.futures下面主要有倆接口 。
ThreadPoolExecutor 線程池 。ProcessPoolExecutor進(jìn)程池 。這里可沒(méi)有什么所謂的異步池 。
個(gè)人看法:雖然異步的性能很高,但是目前除了Go以外,其他實(shí)現(xiàn)的都不是太好,用法上面有些怪異,當(dāng)然,你們可以說(shuō)我菜,我承認(rèn) 。
線程池示例代碼
import timefrom concurrent.futures import ThreadPoolExecutorimport random# max_workers表示工人數(shù)量,也就是線程池里面的線程數(shù)量pool = ThreadPoolExecutor(max_workers=10)# 任務(wù)列表task_list = ["任務(wù)1", "任務(wù)2", "任務(wù)3", "任務(wù)4", ]def handler(task_name):# 隨機(jī)睡眠,模仿任務(wù)執(zhí)行時(shí)間不確定性n = random.randrange(5)time.sleep(n)print(f"任務(wù)內(nèi)容:{task_name}")if __name__ == '__main__':# 遍歷任務(wù),for task in task_list:"""交給函數(shù)處理,submit會(huì)將所有任務(wù)都提交到一個(gè)地方,不會(huì)阻塞然后線程池里面的每個(gè)線程會(huì)來(lái)取任務(wù),比如:線程池有3個(gè)線程,但是有5個(gè)任務(wù)會(huì)先取走三個(gè)任務(wù),每個(gè)線程去處理其中一個(gè)線程處理完自己的任務(wù)之后,會(huì)再來(lái)提交過(guò)的任務(wù)區(qū)再拿走一個(gè)任務(wù)"""pool.submit(handler, task)print("main執(zhí)行完畢")執(zhí)行結(jié)果
發(fā)現(xiàn)的問(wèn)題其實(shí)這個(gè)就是并發(fā)的,不要懷疑,但是你有沒(méi)有發(fā)現(xiàn)個(gè)問(wèn)題,main先執(zhí)行,這說(shuō)明啥?
這說(shuō)明,我main跑完之后,是不管子線程的死活的 。
那能不能設(shè)置一下,所有的子線程都執(zhí)行完之后,main函數(shù)在執(zhí)行完?
當(dāng)然可以,需要一個(gè)參數(shù)即可 。
pool.shutdown()要完成上述的問(wèn)題,我們需要一個(gè)參數(shù),加上這個(gè)參數(shù)之后 。
就可以讓主線程等待所有子線程執(zhí)行完之后,主線程再執(zhí)行完 。
示例代碼
...if __name__ == '__main__':# 遍歷任務(wù),for task in task_list:"""交給函數(shù)處理,submit會(huì)將所有任務(wù)都提交到一個(gè)地方然后線程池里面的每個(gè)線程會(huì)來(lái)取任務(wù),比如:線程池有3個(gè)線程,但是有5個(gè)任務(wù)會(huì)先取走三個(gè)任務(wù),每個(gè)線程去處理其中一個(gè)線程處理完自己的任務(wù)之后,會(huì)再來(lái)提交過(guò)的任務(wù)區(qū)再拿走一個(gè)任務(wù)"""pool.submit(handler, task)pool.shutdown()print("main執(zhí)行完畢")主要就是13行的pool.shutdown() 。
執(zhí)行結(jié)果
這次結(jié)果就是我們想要的了,hhh?。。?br /> add_done_callbackadd_done_callback可以理解為是回調(diào)函數(shù),線程執(zhí)行完之后,會(huì)自動(dòng)調(diào)用指定的回調(diào)函數(shù) 。
并且能拿到線程執(zhí)行函數(shù)的返回值 。
有什么用,我也沒(méi)用過(guò),怪我才疏學(xué)淺叭 。
示例代碼
import timefrom concurrent.futures import ThreadPoolExecutorimport randomfrom concurrent.futures._base import Future# max_workers表示工人數(shù)量,也就是線程池里面的線程數(shù)量pool = ThreadPoolExecutor(max_workers=10)# 任務(wù)列表task_list = ["任務(wù)1", "任務(wù)2", "任務(wù)3", "任務(wù)4", ]def handler(task_name):# 隨機(jī)睡眠,模仿任務(wù)執(zhí)行時(shí)間不確定性n = random.randrange(5)time.sleep(n)print(f"任務(wù)內(nèi)容:{task_name}")return f"任務(wù)內(nèi)容:{task_name}"def done(res: Future):print("done拿到的返回值:", res.result())if __name__ == '__main__':# 遍歷任務(wù),for task in task_list:futrue = pool.submit(handler, task) # type:Futurefutrue.add_done_callback(done)pool.shutdown()print("main執(zhí)行完畢")注意:第17,27,28行代碼!


以上關(guān)于本文的內(nèi)容,僅作參考!溫馨提示:如遇健康、疾病相關(guān)的問(wèn)題,請(qǐng)您及時(shí)就醫(yī)或請(qǐng)專(zhuān)業(yè)人士給予相關(guān)指導(dǎo)!

「愛(ài)刨根生活網(wǎng)」www.malaban59.cn小編還為您精選了以下內(nèi)容,希望對(duì)您有所幫助: