Python 的多執行緒是雞肋?

2022-07-04 22:30:17 字數 2475 閱讀 2188

「唉,還沒畢業就受到甲方的支配,等以後進了公司可咋整啊。」小白嘴裡這麼吐槽,但心理上還是不敢怠慢,只能戀戀不捨地關掉眼前的遊戲,開啟了 python **思考了起來。

「現在的程式是單執行緒的,那就用多執行緒模型來優化吧,嘿嘿,我太機智了!」小白打心底感謝前段時間裡學習到的執行緒的知識。「python 裡好像是threading模組負責多執行緒的,就決定是你了,threading!」

花了兩三個小時,小白終於把程式改好了,他長舒一口氣,點選run,開始測試執行時間。

「woc!怎麼執行時間還變長了?」看著螢幕上顯示的測試結果,小白傻眼了,這多執行緒怎麼不頂用?自己明明是按官方文件來的啊!

debug 無果,小白只好尋求好朋友小明的幫助。

「哈哈哈,你居然用 python 的多執行緒?你不知道python 的多執行緒被很多人稱作「雞肋」嗎?」

「啊,不會吧?還有這種說法?我要是知道我肯定就不用多執行緒來改了。。。可為什麼 python 的多執行緒就雞肋了?那多執行緒爬蟲是怎麼回事?」

「我先給你解釋下 python 下的多執行緒是怎麼一回事吧。python 是一門解釋型語言,它的執行是由直譯器來控制的,我們一般都會使用預設的cpython直譯器,這些我想你應該清楚。」

「那當然,這在一開始學 python 的時候老師就講過了。」

「那你知不知道什麼是gil?」小明問道。

小白撓撓頭,尷尬的回答:「我沒聽說過。」

「也是,你要是知道 gil ,就能弄明白 python 的多執行緒了。gil,全稱是global interpreter lock,全域性解釋鎖 ,專門給直譯器用的。」

「蛤?直譯器還要需要鎖? 」

「這個鎖別有妙用,讓我先考考你,c 語言能不能在使用者態下做到執行緒級別的時間片輪轉?」

「不能!作業系統裡講過了,我還記得上次你教我的內容~」小白得意的回答。

關於執行緒,詳細的在這裡:

「但是 python 能做到!python 裡,直譯器可以記錄每乙個執行緒執行了多長時間——時間一到,就能夠切換到另一條執行緒。」

「有點意思,聽起來像是直譯器充當了作業系統的角色,然後為 python 執行緒提供了時間片輪轉的能力。」

tobe 注:理論上 c 語言也可以做到,畢竟 python 直譯器就是用 c 語言寫的。

「解釋的很到位,我再說回 gil 吧,在多核還沒有出現的時候,就已經有執行緒的存在了,gil 就是拿來給執行緒加鎖的,當乙個執行緒將要執行時,直譯器會把 gil 鎖給這個執行緒,其他執行緒因為沒有鎖,是無法執行的。等到持有鎖線程阻塞或者執行 100 個位元組碼,直譯器就會把鎖交給其他執行緒。」

「但是這個 gil 鎖是全域性(global)的,也就導致即使是多核情況下,一次也只有乙個執行緒能執行,從整體上看,整個程式是序列的。」

小白恍然大悟:「怪不得我的程式還變慢了,原來 python 的多執行緒不僅不能利用多核,還因為執行緒切換拖慢了我程式的執行速度!我想很多人應該都遇到過我這個問題吧,python 社群為什麼不修改這一特性,讓多執行緒也做到並行呢?」

「我好像明白了,」小白感覺自己被打通了任督二脈:「也就是說python 的多執行緒適合 i/o 密集型的程式,但是對計算密集型程式就不那麼友好了~ 誒等等,那我怎麼辦?我還打算用多執行緒優化我的程式呢!」

「讓 python 利用多核的方法還是有的,比如說,讓 python 呼叫 c 語言的**,在 c 語言裡實現多執行緒,因為 c 語言裡沒有 gil 鎖,這些執行緒不會受到 gil 的約束,也就能並行了。」

小白乙個勁兒搖頭:「不不不不不,好不容易寫完的 python **,你讓我改成 c?這不是要我的命嗎!我拒絕!」

「這不是還有第二種方法嘛——使用多程序,python 裡有個multiprocessing模組,可以建立多個程序,因為不同的程序使用不同的直譯器,所以它們有各自的 gil,互不干擾,自然就能完成併發了。

「這個方法聽起來才正常嘛,我馬上就回去試試,謝謝你了!」

希望你在看完我的文章之後有所收穫~(求點贊吶!)

為什麼有人說 Python 多執行緒是雞肋?

為什麼有人會說 python 多執行緒是雞肋?知乎上有人提出這樣乙個問題,在我們常識中,多程序 多執行緒都是通過併發的方式充分利用硬體資源提高程式的執行效率,怎麼在 python 中反而成了雞肋?有同學可能知道答案,因為 python 中臭名昭著的 gil,gil 是什麼?為什麼會有 gil?多線 ...

python中的多執行緒是假的多執行緒

python中的多執行緒是假的多執行緒?為什麼這麼說,我們先明確乙個概念,全域性直譯器鎖 gil global interpreter lock python 的執行由python虛擬機器 直譯器 來控制,同時只有乙個執行緒在執行 對python虛擬機器的訪問由全域性直譯器鎖 gil 來控制,正是這...

python多執行緒 python多執行緒

通常來說,多程序適用於計算密集型任務,多執行緒適用於io密集型任務,如網路爬蟲。關於多執行緒和多程序的區別,請參考這個 下面將使用python標準庫的multiprocessing包來嘗試多執行緒的操作,在python中呼叫多執行緒要使用multiprocessing.dummy,如果是多程序則去掉...