python如何支持并發(fā)方法詳解
由于GIL(Global Interpreter Lock)的存在使得在同一時(shí)刻Python進(jìn)程只能使用CPU的一個(gè)核心,也就是對(duì)應(yīng)操作系統(tǒng)的一個(gè)
內(nèi)核線(xiàn)程,對(duì)于一個(gè)Python web程序,如果有個(gè)請(qǐng)求,并且都是長(zhǎng)耗時(shí)的計(jì)算任務(wù)(占用),這個(gè)程序在接受第一個(gè)請(qǐng)求后
還能處理別的請(qǐng)求么?假如web程序接受到請(qǐng)求就while True了:
def handle_request(request): while True: pass
從代碼上理解,Python只有一個(gè)真正的執(zhí)行線(xiàn)程,代碼走到while True
就占用唯一的一個(gè)cpu核心了,它還有機(jī)會(huì)處理
別的任務(wù)么?
來(lái)啟動(dòng)兩個(gè)線(xiàn)程都進(jìn)行while True ,觀(guān)察他們是否都能執(zhí)行來(lái)模擬那兩個(gè)請(qǐng)求:
import time, threading def f1(name): while True: print(name) time.sleep(1) threading.Thread(target=f1, args=('f1', )).start() threading.Thread(target=f1, args=('f2', )).start()
輸出結(jié)果:
f1
f2
f2f1f2
f1
...
實(shí)際上使用Django(一個(gè)Python Web 框架)測(cè)試,即使一個(gè)請(qǐng)求執(zhí)行了while True
這樣的代碼,它還是可以處理別的請(qǐng)求(支持并發(fā));
來(lái)解釋一下為什么兩個(gè)while True
都能執(zhí)行:
還是用GIL這把鎖,第一個(gè)while True
的線(xiàn)程拿到這把鎖才能執(zhí)行,然后它執(zhí)行了一個(gè)print(name)
接著把鎖釋放了,
它就暫停了,接著第二個(gè)while True
線(xiàn)程拿到GIL后開(kāi)始執(zhí)行,圍繞GIL交替執(zhí)行,就實(shí)現(xiàn)了Python的多線(xiàn)程。
總結(jié)一下:
while True
也不能一直持有CPU資源,它也是執(zhí)行一會(huì)歇一會(huì),這就給了其他進(jìn)程機(jī)會(huì),這里面有兩個(gè)關(guān)鍵點(diǎn):
- 如何搶到這把鎖
- 如何釋放鎖
搶鎖,排隊(duì)。給lock安排一個(gè)隊(duì)列,想執(zhí)行的進(jìn)這個(gè)隊(duì)列。
釋放鎖的有點(diǎn)類(lèi)似進(jìn)程調(diào)度:
- 劃分時(shí)間片(執(zhí)行一樣的時(shí)間)
- 執(zhí)行指令計(jì)數(shù)(執(zhí)行一樣的指令次數(shù))
- 碰到IO操作(被動(dòng)等待)
- 主動(dòng)等待(wait/join/sleep)
碰到IO操作,需要等待IO設(shè)備完成計(jì)算才能繼續(xù)執(zhí)行線(xiàn)程,這段時(shí)間內(nèi)不占用CPU資源,先把鎖釋放了。
主動(dòng)等待,典型的就是sleep,主動(dòng)放棄鎖,等到一定時(shí)機(jī)再重新執(zhí)行。
以上分析 說(shuō)明Python支持并發(fā),但是由于無(wú)法利用多核處理器優(yōu)勢(shì),對(duì)于大量并發(fā)下的計(jì)算密集型應(yīng)用
不適合使用Python。
到此這篇關(guān)于python如何支持并發(fā)的文章就介紹到這了,更多相關(guān)python支持并發(fā)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- python 實(shí)現(xiàn)socket服務(wù)端并發(fā)的四種方式
- selenium+python實(shí)現(xiàn)登陸QQ郵箱并發(fā)送郵件功能
- Python使用grequests(gevent+requests)并發(fā)發(fā)送請(qǐng)求過(guò)程解析
- Python使用socket模塊實(shí)現(xiàn)簡(jiǎn)單tcp通信
- 基于python實(shí)現(xiàn)藍(lán)牙通信代碼實(shí)例
- Python實(shí)現(xiàn)串口通信(pyserial)過(guò)程解析
- 分析python并發(fā)網(wǎng)絡(luò)通信模型
相關(guān)文章
Windows上使用Python增加或刪除權(quán)限的方法
下面小編就為大家分享一篇Windows上使用Python增加或刪除權(quán)限的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-04-04Python分類(lèi)測(cè)試代碼實(shí)例匯總
這篇文章主要介紹了Python分類(lèi)測(cè)試代碼實(shí)例匯總,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07jupyter的安裝與使用以及運(yùn)行卡頓問(wèn)題及解決
這篇文章主要介紹了jupyter的安裝與使用以及運(yùn)行卡頓問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06python使用PyGame實(shí)現(xiàn)打磚塊游戲
打磚塊也是一個(gè)非常經(jīng)典的小游戲,玩法大致如下,用一個(gè)小車(chē)接一個(gè)小球,然后反射小球,使之打在磚塊上,當(dāng)小球碰到磚塊之后,則磚塊被消掉,邏輯十分清晰,本文將給大家介紹了python使用PyGame實(shí)現(xiàn)打磚塊游戲,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下2023-12-12OpenCV實(shí)現(xiàn)圖片編解碼實(shí)踐
在很多應(yīng)用中,經(jīng)常會(huì)直接把圖片的二進(jìn)制數(shù)據(jù)進(jìn)行交換,這就需要對(duì)普通進(jìn)行編碼解碼,那么怎么才能實(shí)現(xiàn),本文就來(lái)介紹一下2021-06-06詳解Python3操作Mongodb簡(jiǎn)明易懂教程
本篇文章主要介紹了詳解Python3操作Mongodb簡(jiǎn)明易懂教程,詳細(xì)的介紹了如何連接數(shù)據(jù)庫(kù)和對(duì)數(shù)據(jù)庫(kù)的操作,有需要的可以了解一下。2017-05-05python通過(guò)socket查詢(xún)whois的方法
這篇文章主要介紹了python通過(guò)socket查詢(xún)whois的方法,涉及Python基于socket模塊進(jìn)行查詢(xún)的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07詳解Python如何獲取視頻文件的大小和時(shí)長(zhǎng)
這篇文章主要為大家詳細(xì)介紹了Python如何實(shí)現(xiàn)獲取視頻文件的大小和時(shí)長(zhǎng),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2023-03-03pandas實(shí)現(xiàn)滑動(dòng)窗口的示例代碼
本文主要介紹了pandas實(shí)現(xiàn)滑動(dòng)窗口的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03