Python多進(jìn)程與多線程的使用場(chǎng)景詳解
前言
Python多進(jìn)程適用的場(chǎng)景:計(jì)算密集型(CPU密集型)任務(wù)
Python多線程適用的場(chǎng)景:IO密集型任務(wù)
計(jì)算密集型任務(wù)一般指需要做大量的邏輯運(yùn)算,比如上億次的加減乘除,使用多核CPU可以并發(fā)提高計(jì)算性能。
IO密集型任務(wù)一般指輸入輸出型,比如文件的讀取,或者網(wǎng)絡(luò)的請(qǐng)求,這類場(chǎng)景一般會(huì)遇到IO阻塞,使用多核CPU來(lái)執(zhí)行并不會(huì)有太高的性能提升。
下面使用一臺(tái)64核的虛擬機(jī)來(lái)執(zhí)行任務(wù),通過(guò)示例代碼來(lái)區(qū)別它們,
示例1:執(zhí)行計(jì)算密集型任務(wù),進(jìn)行1億次運(yùn)算
使用多進(jìn)程
from multiprocessing import Process
import os, time
# 計(jì)算密集型任務(wù)
def work():
res = 0
for i in range(100 * 100 * 100 * 100): # 億次運(yùn)算
res *= i
if __name__ == "__main__":
l = []
print("本機(jī)為", os.cpu_count(), "核 CPU") # 本機(jī)為64核
start = time.time()
for i in range(4):
p = Process(target=work) # 多進(jìn)程
l.append(p)
p.start()
for p in l:
p.join()
stop = time.time()
print("計(jì)算密集型任務(wù),多進(jìn)程耗時(shí) %s" % (stop - start))
使用多線程
from threading import Thread
import os, time
# 計(jì)算密集型任務(wù)
def work():
res = 0
for i in range(100 * 100 * 100 * 100): # 億次運(yùn)算
res *= i
if __name__ == "__main__":
l = []
print("本機(jī)為", os.cpu_count(), "核 CPU") # 本機(jī)為64核
start = time.time()
for i in range(4):
p = Thread(target=work) # 多線程
l.append(p)
p.start()
for p in l:
p.join()
stop = time.time()
print("計(jì)算密集型任務(wù),多線程耗時(shí) %s" % (stop - start))
兩段代碼輸出:
本機(jī)為 64 核 CPU
計(jì)算密集型任務(wù),多進(jìn)程耗時(shí) 6.864224672317505
本機(jī)為 64 核 CPU
計(jì)算密集型任務(wù),多線程耗時(shí) 37.91042113304138
說(shuō)明:上述代碼中,分別使用4個(gè)多進(jìn)程和4個(gè)多線程去執(zhí)行億次運(yùn)算,多進(jìn)程耗時(shí)6.86s,多線程耗時(shí)37.91s,可見(jiàn)在計(jì)算密集型任務(wù)場(chǎng)景,使用多進(jìn)程能大大提高效率。
另外,當(dāng)分別使用8個(gè)多進(jìn)程和8個(gè)多線程去執(zhí)行億次運(yùn)算時(shí),耗時(shí)差距更大,輸出如下:
本機(jī)為 64 核 CPU
計(jì)算密集型任務(wù),多進(jìn)程耗時(shí) 6.811635971069336
本機(jī)為 64 核 CPU
計(jì)算密集型任務(wù),多線程耗時(shí) 113.53767895698547
可見(jiàn)在64核的cpu機(jī)器下,同時(shí)使用8個(gè)多進(jìn)程和4個(gè)多進(jìn)程效率幾乎一樣。而使用多線程則就效率較慢。要最高效地利用CPU,計(jì)算密集型任務(wù)同時(shí)進(jìn)行的數(shù)量應(yīng)當(dāng)?shù)扔贑PU的核心數(shù)
示例2:400次,阻塞兩秒,讀取文件
使用多進(jìn)程(4核cpu)
from multiprocessing import Process
import os, time
# I/0密集型任務(wù)
def work():
time.sleep(5) # 阻塞兩秒
if __name__ == "__main__":
l = []
print("本機(jī)為", os.cpu_count(), "核 CPU")
start = time.time()
for i in range(1000):
p = Process(target=work) # 多進(jìn)程
l.append(p)
p.start()
for p in l:
p.join()
stop = time.time()
print("I/0密集型任務(wù),多進(jìn)程耗時(shí) %s" % (stop - start))
使用多線程(4核cpu)
from threading import Thread
import os, time
# I/0密集型任務(wù)
def work():
time.sleep(5) # 阻塞兩秒
if __name__ == "__main__":
l = []
print("本機(jī)為", os.cpu_count(), "核 CPU")
start = time.time()
for i in range(1000):
p = Thread(target=work) # 多線程
l.append(p)
p.start()
for p in l:
p.join()
stop = time.time()
print("I/0密集型任務(wù),多線程耗時(shí) %s" % (stop - start))
輸出:
本機(jī)為 64 核 CPU
I/0密集型任務(wù),多進(jìn)程耗時(shí) 12.28218412399292
本機(jī)為 64 核 CPU
I/0密集型任務(wù),多線程耗時(shí) 5.399136066436768
說(shuō)明:python的多線程有于GIL鎖的存在,無(wú)論是多少核的cpu機(jī)器,也只能使用單核,從輸出結(jié)果來(lái)看,對(duì)于IO密集型任務(wù)使用多線程比較占優(yōu)。
FAQ:執(zhí)行多進(jìn)程的io密集型任務(wù)時(shí),報(bào)了一個(gè)錯(cuò):
OSError: [Errno 24] Too many open files
原因:linux系統(tǒng)限制
ulimit -n # 輸出 1024
解決:(臨時(shí)提高系統(tǒng)限制,重啟后失效)
ulimit -n 10240
總結(jié)
到此這篇關(guān)于Python多進(jìn)程與多線程使用場(chǎng)景的文章就介紹到這了,更多相關(guān)Python多進(jìn)程與使用場(chǎng)景內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
padas 生成excel 增加sheet表的實(shí)例
今天小編就為大家分享一篇padas 生成excel 增加sheet表的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-12-12
Django利用LogEntry生成歷史操作實(shí)戰(zhàn)記錄
LogEntry是在后臺(tái)開發(fā)中經(jīng)常用到的模塊,它在admin是默認(rèn)開啟的。文中給大家介紹了在admin頁(yè)面上查看操作日志的方法及實(shí)戰(zhàn)代碼,感興趣的朋友跟隨小編一起看看吧2021-12-12
Python使用try-except捕獲與處理異常的實(shí)現(xiàn)方法
在Python中,try-except 語(yǔ)句是用于捕獲和處理異常的主要工具,當(dāng)程序運(yùn)行過(guò)程中發(fā)生錯(cuò)誤時(shí),try-except 結(jié)構(gòu)可以有效地防止程序崩潰,并允許開發(fā)者為錯(cuò)誤提供適當(dāng)?shù)慕鉀Q方案,接下來(lái),我們將詳細(xì)探討 try-except 的使用方式,需要的朋友可以參考下2024-11-11
python使用htmllib分析網(wǎng)頁(yè)內(nèi)容的方法
這篇文章主要介紹了python使用htmllib分析網(wǎng)頁(yè)內(nèi)容的方法,涉及Python使用htmllib模塊的相關(guān)技巧,需要的朋友可以參考下2015-05-05
Python 轉(zhuǎn)移文件至云對(duì)象存儲(chǔ)的方法
對(duì)象存儲(chǔ)(Cloud Object Storage,COS)是一種存儲(chǔ)海量文件的分布式存儲(chǔ)服務(wù),具有高擴(kuò)展性、低成本、可靠安全等優(yōu)點(diǎn)。這篇文章主要介紹了Python 轉(zhuǎn)移文件至云對(duì)象存儲(chǔ),需要的朋友可以參考下2021-02-02
Python新手在作用域方面經(jīng)常容易碰到的問(wèn)題
這篇文章主要介紹了Python新手在作用域方面經(jīng)常容易碰到的問(wèn)題,全局變量和局部變量方面的知識(shí)在Python學(xué)習(xí)當(dāng)中是基礎(chǔ)中的基礎(chǔ),需要的朋友可以參考下2015-04-04

