如果有一大批數(shù)據(jù)镣奋,需要根據(jù)一定的邏輯完成數(shù)據(jù)處理,你可能會有如下幾種情況:
- 不引入并發(fā)怀愧,編寫的腳本執(zhí)行效率很低
- 想要引入并發(fā)侨颈,但是不會用
- 學(xué)過多進程、多線程和多協(xié)程芯义,但是不知道當(dāng)下這種情況該選哪種
下面我們就來做一下探討哈垢!
一、選型問題
- 進程
1扛拨、首先耘分,如果線程、協(xié)程都解決不了你的問題绑警,則考慮一下使用進程(進程開銷大求泰,所以優(yōu)先考慮線程、協(xié)程)
2计盒、其次渴频,需要確認你程序要運行的機器的cpu的核數(shù),linux可以使用命令cat /proc/cpuinfo |grep "processor"|sort -u|wc -l
查看北启。如果你的cpu核數(shù)較為理想(需要同時考慮其他程序的進程的占用而確定卜朗,比如運行在這臺機器上的一些軟件什么的),且你可以搞定進程間通信咕村,可以選擇進程场钉。
3、當(dāng)然懈涛,如果你的cpu只有一個核逛万,這意味著同一時間只能有一個進程在占用cpu,則選擇多進程完全不會有任何提效批钠。 - 線程
1宇植、如果想要使用線程得封,就不得不對python解釋器CPython的底層GIL有一定的了解
2、其次当纱,分析一下你的業(yè)務(wù)場景中IO操作(如文件讀寫呛每、網(wǎng)絡(luò)傳輸)的占比踩窖。如果IO操作不多(即CPU密集型)的話坡氯,python的多線程不是一個好的選擇,因為這意味著各線程都要占用cpu洋腮,但是GIL決定了同一時間只能有一個線程占用cpu箫柳,所以針對IO操作較多(即IO密集型)的程序,多線程或許是你的一個比較好的選擇啥供,因為多線程相對編碼容易悯恍,且IO多就促成了cpu可以空出時間去做其他的事情,效率自然也就提高了伙狐。
3涮毫、當(dāng)然,使用多線程時并非線程數(shù)越多越快贷屎,因為系統(tǒng)切換線程也存在較大的開銷罢防,開發(fā)者應(yīng)盡可能找到最佳的臨界點,以最大化執(zhí)行效率唉侄。 - 協(xié)程
1咒吐、對比多進程,協(xié)程開銷小且不需要考慮同步問題
2属划、針對IO密集型程序恬叹,并發(fā)數(shù)量較多的情況下,可能比多線程效率要高同眯,對比線程數(shù)越多的多線程程序協(xié)程的優(yōu)勢就越明顯(由于GIL的限制绽昼,多線程主要是敗在了線程切換的開銷,線程數(shù)越多须蜗,開銷越大)绪励;針對CPU密集型程序,無優(yōu)勢唠粥。
3疏魏、協(xié)程是異步的,當(dāng)遇到IO操作晤愧,會中斷轉(zhuǎn)而去處理其他任務(wù)大莫,等IO結(jié)束返回來繼續(xù)處理。 - 多進程+協(xié)程
如果cpu夠用官份,可考慮多進程+協(xié)程結(jié)合使用只厘。既充分利用了多核烙丛,又發(fā)揮了協(xié)程的高效率,可獲得極高的性能羔味。
總的來說河咽,CPU密集型選多進程,IO密集型看線程并發(fā)量斟酌選多線程或協(xié)程赋元,想發(fā)揮出多核cpu最大優(yōu)勢忘蟹,選多進程+協(xié)程。
二搁凸、demo
1媚值、多進程
待補充
2、多線程
import threading
from math import ceil
def test(data, threadNums):
num = len(data)
n = int(threading.currentThread().getName())
# 避免不能整除
count = ceil(num / threadNums)
for i in range(n * count, (n + 1) * count):
# 不能越界
if i < num:
print(data[i]) # 這里替換為業(yè)務(wù)邏輯
# data為數(shù)據(jù)列表(或字典等其他類型护糖,根據(jù)實際業(yè)務(wù)情況而定)褥芒,threadNum為線程數(shù)
def testThread(data, threadNum):
threadList = []
for i in range(threadNum):
thread = threading.Thread(target=test, args=(data, threadNum), name="{}".format(i))
thread.start()
threadList.append(thread)
for j in threadList:
j.join()
if __name__ == '__main__':
testThread([i for i in range(10)], 3)
3、多協(xié)程
待補充
4嫡良、多進程+協(xié)程
待補充
END~
參考:
廖雪峰的官方網(wǎng)站
python中的GIL詳解
淺析Python的進程锰扶、線程與協(xié)程
【python】python進程、線程寝受、協(xié)程和什么時候使用