今天在學(xué)python協(xié)程的時(shí)候有一些疑惑绞佩,向源源大神請(qǐng)教了一下寺鸥,學(xué)到好多,總結(jié)一下品山。
python是線程安全的
python語(yǔ)言的基本數(shù)據(jù)結(jié)構(gòu)設(shè)定的時(shí)候就是線程安全的胆建,一個(gè)線程執(zhí)行的時(shí)候,會(huì)有GIL鎖肘交,別的線程拿不到鎖無(wú)法執(zhí)行笆载,所以python沒辦法多線程并發(fā)。所以python的多線程是個(gè)特例涯呻。
CPU的最小調(diào)度單元是線程不是進(jìn)程凉驻,所以單進(jìn)程多線程也可以利用多核CPU
以前學(xué)操作系統(tǒng)的時(shí)候,記得CPU一次只能執(zhí)行一個(gè)進(jìn)程复罐,別的進(jìn)程只能等待涝登。沒有錯(cuò),但是要明確一點(diǎn) “CPU的最小調(diào)度單元是線程不是進(jìn)程”效诅。
項(xiàng)目一般分類為計(jì)算密集型和IO密集型
對(duì)于I/O密集型胀滚,一般不會(huì)用python做趟济,因?yàn)椴荒苡枚嗑€程。
對(duì)于異步I/O咽笼,雖然不能利用多線程顷编,但是可以利用協(xié)程
python2的gevent或是greenlet庫(kù)是python3的async io出來(lái)前的協(xié)程解決方案
但是gevent和greenlet的學(xué)習(xí)成本比較大,對(duì)于I/O密集型可以選擇golang褐荷。
golang的語(yǔ)言特性
goalng沒有多進(jìn)程勾效,它是單進(jìn)程:m線程:n協(xié)程的結(jié)構(gòu),由于CPU的執(zhí)行最小單元是線程叛甫,所以golang可以有效利用多核。但是golang的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)比如map就不是線程安全杨伙,有時(shí)候要考慮加鎖其监。那么在加鎖的情況下,golang其實(shí)這段代碼其實(shí)同時(shí)只有一個(gè)協(xié)程可以跑限匣。
golang的協(xié)程
golang的goroutine是語(yǔ)言自帶的協(xié)程,實(shí)現(xiàn)起來(lái)沒有歷史包袱抖苦,可以有效的利用多核,在一些新內(nèi)核特性的支持下米死,它的I/O處理性能可以非承坷恐怖。并且編程復(fù)雜度也不是很高峦筒。
協(xié)程
一般來(lái)說(shuō)協(xié)程都是n:m的協(xié)程究西,即n個(gè)協(xié)程在m個(gè)線程里跑,有一個(gè)runtime協(xié)程作為調(diào)度物喷,所以可以有效利用多核卤材。
但是python的協(xié)程是n:1的協(xié)程,即n個(gè)協(xié)程在1個(gè)線程里跑峦失,可以實(shí)現(xiàn)異步I/O扇丛,但是不能有效利用多核。
對(duì)于I/O 密集型尉辑,python可以利用協(xié)程來(lái)解決帆精,有非阻塞I/O,不需要多核隧魄,比如node就是計(jì)算單線程卓练,I/O用的內(nèi)部的線程池。Python加入async io后堤器,可能會(huì)對(duì)一些場(chǎng)景下的io性能有提升
python的協(xié)程庫(kù)
gevent(greenlet)應(yīng)該可以用n:m協(xié)程模式昆庇。python把輸入給gevent模塊,gevent自己里面的C模塊調(diào)用新的一套進(jìn)程線程模式闸溃,把結(jié)果返回給python整吆。所謂的n:m指的是gevent里的實(shí)現(xiàn)拱撵,跟python沒什么關(guān)系,是透明的表蝙,所以可以是n:m模式拴测。(所謂“語(yǔ)言的擴(kuò)展”用另一門語(yǔ)言來(lái)擴(kuò)充當(dāng)前語(yǔ)言的語(yǔ)法,相當(dāng)與你擴(kuò)充了Python的語(yǔ)法用法特性)
庫(kù)
庫(kù)分為原生的和二進(jìn)制封裝的府蛇。原生代碼就是說(shuō)用Python寫了一個(gè)Python庫(kù)集索,然后用Python執(zhí)行它,它的所有特性都在Python解釋器的語(yǔ)法用法范圍內(nèi)汇跨。但是也可以用C寫一個(gè)Python庫(kù)务荆,編譯成動(dòng)態(tài)鏈接庫(kù),然后在Python里面執(zhí)行它穷遂,執(zhí)行到這個(gè)庫(kù)的時(shí)候函匕,邏輯就到了的動(dòng)態(tài)鏈接庫(kù)里,這個(gè)時(shí)候Python解釋器是控制不了的蚪黑,也就相當(dāng)與擴(kuò)充了Python的語(yǔ)法用法特性盅惜。平常所見的NumPy,Gevent忌穿,TensorFlow都是后者抒寂。
對(duì)于計(jì)算密集型
對(duì)于計(jì)算密集型,python和node之類的就要利用多進(jìn)程來(lái)彌補(bǔ)計(jì)算資源的不足掠剑,但是golang多線程就會(huì)比較自然了屈芜。
由一個(gè)協(xié)程問題請(qǐng)教了這么多,不是說(shuō)golang比python好澡腾,只是在某些特性方面各有利弊沸伏。python類似一個(gè)膠水語(yǔ)言,簡(jiǎn)單易學(xué)易上手动分,入手快毅糟,不用編譯,腳本型語(yǔ)言澜公,然后在高性能庫(kù)/應(yīng)用中間做一個(gè)膠水姆另。但是這么好上手還是學(xué)起來(lái)。
最后發(fā)個(gè)源源大神愛的抱抱~ 筆芯~ ????????????????????