国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

python并發(fā)2之使用asyncio處理并發(fā)

2020-02-16 11:14:43
字體:
供稿:網(wǎng)友

asyncio

在Python 2的時代,高性能的網(wǎng)絡(luò)編程主要是使用Twisted、Tornado和Gevent這三個庫,但是它們的異步代碼相互之間既不兼容也不能移植。如上一節(jié)說的,Gvanrossum希望在Python 3 實現(xiàn)一個原生的基于生成器的協(xié)程庫,其中直接內(nèi)置了對異步IO的支持,這就是asyncio,它在Python 3.4被引入到標(biāo)準(zhǔn)庫。

asyncio 這個包使用事件循環(huán)驅(qū)動的協(xié)程實現(xiàn)并發(fā)。

asyncio 包在引入標(biāo)準(zhǔn)庫之前代號 “Tulip”(郁金香),所以在網(wǎng)上搜索資料時,會經(jīng)常看到這種花的名字。

什么是事件循環(huán)?

wiki 上說:事件循環(huán)是”一種等待程序分配事件或者消息的編程架構(gòu)“。基本上來說事件循環(huán)就是:”當(dāng)A發(fā)生時,執(zhí)行B"。或者用最簡單的例子來解釋這一概念就是每個瀏覽器中都存在的JavaScript事件循環(huán)。當(dāng)你點擊了某個東西(“當(dāng)A發(fā)生時”),這一點擊動作會發(fā)送給JavaScript的事件循環(huán),并檢查是否存在注冊過的onclick 回調(diào)來處理這一點擊(執(zhí)行B)。只要有注冊過的回調(diào)函數(shù)就會伴隨點擊動作的細(xì)節(jié)信息被執(zhí)行。事件循環(huán)被認(rèn)為是一種虛幻是因為它不停的手機事件并通過循環(huán)來發(fā)如何應(yīng)對這些事件。

對 Python 來說,用來提供事件循環(huán)的 asyncio 被加入標(biāo)準(zhǔn)庫中。asyncio 重點解決網(wǎng)絡(luò)服務(wù)中的問題,事件循環(huán)在這里將來自套接字(socket)的 I/O 已經(jīng)準(zhǔn)備好讀和/或?qū)懽鳛椤爱?dāng)A發(fā)生時”(通過selectors模塊)。除了 GUI 和 I/O,事件循環(huán)也經(jīng)常用于在別的線程或子進程中執(zhí)行代碼,并將事件循環(huán)作為調(diào)節(jié)機制(例如,合作式多任務(wù))。如果你恰好理解 Python 的 GIL,事件循環(huán)對于需要釋放 GIL 的地方很有用。

線程與協(xié)程

我們先看兩斷代碼,分別用 threading 模塊和asyncio 包實現(xiàn)的一段代碼。

# sinner_thread.pyimport threadingimport itertoolsimport timeimport sysclass Signal: # 這個類定義一個可變對象,用于從外部控制線程 go = Truedef spin(msg, signal): # 這個函數(shù)會在單獨的線程中運行,signal 參數(shù)是前邊定義的Signal類的實例 write, flush = sys.stdout.write, sys.stdout.flush for char in itertools.cycle('|/-//'): # itertools.cycle 函數(shù)從指定的序列中反復(fù)不斷地生成元素  status = char + ' ' + msg  write(status)  flush()  write('/x08' * len(status)) # 使用退格符把光標(biāo)移回行首  time.sleep(.1) # 每 0.1 秒刷新一次  if not signal.go: # 如果 go屬性不是 True,退出循環(huán)   break write(' ' * len(status) + '/x08' * len(status)) # 使用空格清除狀態(tài)消息,把光標(biāo)移回開頭def slow_function(): # 模擬耗時操作 # 假裝等待I/O一段時間 time.sleep(3) # 調(diào)用sleep 會阻塞主線程,這么做事為了釋放GIL,創(chuàng)建從屬線程 return 42def supervisor(): # 這個函數(shù)設(shè)置從屬線程,顯示線程對象,運行耗時計算,最后殺死進程 signal = Signal() spinner = threading.Thread(target=spin,        args=('thinking!', signal)) print('spinner object:', spinner) # 顯示線程對象 輸出 spinner object: <Thread(Thread-1, initial)> spinner.start() # 啟動從屬進程 result = slow_function() # 運行slow_function 行數(shù),阻塞主線程。同時叢書線程以動畫形式旋轉(zhuǎn)指針 signal.go = False spinner.join() # 等待spinner 線程結(jié)束 return resultdef main(): result = supervisor()  print('Answer', result)if __name__ == '__main__': main()            
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 工布江达县| 奉节县| 松溪县| 德昌县| 临夏县| 平度市| 康乐县| 祁连县| 长垣县| 长丰县| 潜江市| 新宁县| 达州市| 阿克陶县| 连山| 甘泉县| 宜昌市| 盱眙县| 全州县| 绍兴县| 舟曲县| 河曲县| 时尚| 儋州市| 健康| 平顺县| 广元市| 佛坪县| 同德县| 萨嘎县| 珠海市| 汝阳县| 达尔| 威远县| 剑阁县| 宿松县| 贵阳市| 北宁市| 鄂州市| 合山市| 深泽县|