本文目錄一覽:
- 1、協程與非同步IO
- 2、python協程和非同步IO——IO多路復用
- 3、python培訓入門教程?怎樣入門呢?
- 4、Python用asyncio模塊做協程非同步IO爬蟲功能,為啥我這兩個模塊下的代碼錯誤這麼多!
協程與非同步IO
協程,又稱微線程,纖程。英文名 Coroutine 。Python對協程的支持是通過 generator 實現的。在generator中,我們不但可以通過for循環來迭代,還可以不斷調用 next()函數 獲取由 yield 語句返回的下一個值。但是Python的yield不但可以返回一個值,它還可以接收調用者發出的參數。yield其實是終端當前的函數,返回給調用方。python3中使用yield來實現range,節省內存,提高性能,懶載入的模式。
asyncio是Python 3.4 版本引入的 標準庫 ,直接內置了對非同步IO的支持。
從Python 3.5 開始引入了新的語法 async 和 await ,用來簡化yield的語法:
import asyncio
import threading
async def compute(x, y):
print(“Compute %s + %s …” % (x, y))
print(threading.current_thread().name)
await asyncio.sleep(x + y)
return x + y
async def print_sum(x, y):
result = await compute(x, y)
print(“%s + %s = %s” % (x, y, result))
print(threading.current_thread().name)
if __name__ == “__main__”:
loop = asyncio.get_event_loop()
tasks = [print_sum(1, 2), print_sum(3, 4)]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
線程是內核進行搶佔式的調度的,這樣就確保了每個線程都有執行的機會。而 coroutine 運行在同一個線程中,由語言的運行時中的 EventLoop(事件循環) 來進行調度。和大多數語言一樣,在 Python 中,協程的調度是非搶佔式的,也就是說一個協程必須主動讓出執行機會,其他協程才有機會運行。
讓出執行的關鍵字就是 await。也就是說一個協程如果阻塞了,持續不讓出 CPU,那麼整個線程就卡住了,沒有任何並發。
PS: 作為服務端,event loop最核心的就是IO多路復用技術,所有來自客戶端的請求都由IO多路復用函數來處理;作為客戶端,event loop的核心在於利用Future對象延遲執行,並使用send函數激發協程,掛起,等待服務端處理完成返回後再調用CallBack函數繼續下面的流程
Go語言的協程是 語言本身特性 ,erlang和golang都是採用了CSP(Communicating Sequential Processes)模式(Python中的協程是eventloop模型),但是erlang是基於進程的消息通信,go是基於goroutine和channel的通信。
Python和Go都引入了消息調度系統模型,來避免鎖的影響和進程/線程開銷大的問題。
協程從本質上來說是一種用戶態的線程,不需要系統來執行搶佔式調度,而是在語言層面實現線程的調度 。因為協程 不再使用共享內存/數據 ,而是使用 通信 來共享內存/鎖,因為在一個超級大系統里具有無數的鎖,共享變數等等會使得整個系統變得無比的臃腫,而通過消息機制來交流,可以使得每個並發的單元都成為一個獨立的個體,擁有自己的變數,單元之間變數並不共享,對於單元的輸入輸出只有消息。開發者只需要關心在一個並發單元的輸入與輸出的影響,而不需要再考慮類似於修改共享內存/數據對其它程序的影響。
python協程和非同步IO——IO多路復用
C10k是一個在1999年被提出來的技術挑戰,如何在一顆1GHz CPU,2G內存,1gbps網路環境下,讓單台伺服器同時為1萬個客戶端提供FTP服務
阻塞式I/O(使用最多)、非阻塞式I/O、I/O復用、信號驅動式I/O(幾乎不使用)、非同步I/O(POSIX的aio_系列函數)
select、poll、epoll都是IO多路復用的機制。I/O多路復用就是通過一種機制,一個進程可以監聽多個描述符,一旦,某個描述符就緒(一般是讀就緒或者寫就緒),能夠通知程序進行相應的讀寫操作。但select、poll、epoll本質上都是同步I/O,因為他們都需要在讀寫時間就緒後負責進行讀寫,也就是說讀寫過程是阻塞的,而非同步I/O無需自己負責進行讀寫,非同步I/O的實現會負責把數據從內核拷貝到用戶空間
(1)select
select函數監視的文件描述符分3類,分別是writefds、readfds、exceptfds。調用select函數會阻塞,直到有描述符就緒(有數據可讀、可寫或者有except),或者超時函數返回。當select函數返回後可以通過遍歷fdset來找到就緒的描述符。
select目前幾乎在所有的平台上支持,其良好的跨平台支持也是它的一個優點。select的一個缺點在於單個進程能夠監視的文件描述符的數量存在最大限制,在Linux上一般為1024,可以通過修改宏定義甚至重新編譯內核的方式提升這一限制,但是這樣也會降低效率。
(2)poll
不同於select使用三個點陣圖來表示三個fdset的方式,poll使用一個pollfd的指針實現。
pollfd結構包含了要監視的event和發生的event,不再使用select”參數-值”傳遞的方式。同時pollfd並沒有最大數量限制(但是數量過大後性能也會下降)。和select函數一樣,poll返回後,需要輪詢pollfd來獲取就緒的描述符。
從上面看,select和poll都需要在返回後通過遍歷文件描述符來獲取已經就緒的socket。事實上同時連接的大量客戶端在同一時刻可能只有很少的處於就緒的狀態,因此隨著監視的描述符數量的增長,其效率也會線性下降
(3)epoll
epoll是在2.6內核中提出的,是之前的select和poll的增強版本。相對於select和poll來說,epoll更加領靈活,沒有描述符限制。epoll使用一個文件描述符管理多個描述符,將用戶關係的文件描述符的事件存放到內核的一個事件表中,這樣在用戶空間和內核空間的copy只需一次。
python培訓入門教程?怎樣入門呢?
python作為一個編程語言,具有與其他編程語言同等的能力。冠冕堂皇地講,是所有語言都是圖靈等價的。不過python作為一門語言,尤其獨特的優點,簡單易學,內置了很多庫。也很容易擴展。Python培訓課程如何學?
可以選一本通俗易懂的書,找一個好的視頻資料,然後自己裝一個IDE工具開始邊學邊寫。下面我具體來講講:
1.找一本靠譜的書,難度一定要是入門級別,千萬不能太複雜,不要一下子陷進去,會打亂節奏,學東西要循序漸進,不能一口吃個胖子.打個比方,學過java的同學都聽過大名鼎鼎的thinking in java,這邊書很厚很全,若一上來就學,肯定會吃力,時間長了就會失去興趣,因此對初學者來說,一定要找一本通熟易懂的,簡單的書。入門的書非常關鍵。
入門的書很多,但是我個人強烈推薦《A Byte of Python》,這本書我讀了2遍,作者寫作思路非常清晰,對每個知識點講解很到位,不多不少。對初學者來說,力道剛剛好。而且是全英文,對提高自己的英語水平也很有幫助。
網上有人會推薦《笨辦法學Python》,我個人覺得這本書沒有《A Byte of Python》好 。一般有一些編程基本,我建議直接看《A Byte of Python》。這本書的銷量已經破百萬了,而且在豆瓣上點評有8.8,可謂是入門級的神書.電子版大家可以在CSDN 搜一下就有,都是高清的。
2.找一個靠譜的師傅。Python編程是一個十分系統的技術體系,有時候光靠看書和網上的視頻,只能是一知半解,遇到問題,沒有人給你講解其中的原理和流程,那麼對於整個技術點的理解就永遠不會通透。況且,編程不只是知識,還涉及到做具體的項目,在做項目中,如果有人帶,進步才是最神速的。
3.多編寫程序,這似乎是廢話,但是確實是一句實話。學編程一定要親身去編寫,沒有什麼捷徑。一開始哪怕你把書裡面的例子一字不落敲一遍,也好過你只是去看書,而不動手。
而且學python 最好是堅持編,每天抽小半個小時,學一些知識點,不斷堅持.快的話幾個星期基本就能入門了。
Python用asyncio模塊做協程非同步IO爬蟲功能,為啥我這兩個模塊下的代碼錯誤這麼多!
隨著node.js的盛行,相信大家今年多多少少都聽到了非同步編程這個概念。Python社區雖然對於非同步編程的支持相比其他語言稍顯遲緩,但是也在Python3.4中加入了asyncio,在Python3.5上又提供了async/await語法層面的支持,剛正式發布的Python3.6中asynico也已經由臨時版改為了穩定版。下面我們就基於Python3.4+來了解一下非同步編程的概念以及asyncio的用法。
什麼是協程
通常在Python中我們進行並發編程一般都是使用多線程或者多進程來實現的,對於計算型任務由於GIL的存在我們通常使用多進程來實現,而對與IO型任務我們可以通過線程調度來讓線程在執行IO任務時讓出GIL,從而實現表面上的並發。
其實對於IO型任務我們還有一種選擇就是協程,協程是運行在單線程當中的「並發」,協程相比多線程一大優勢就是省去了多線程之間的切換開銷,獲得了更大的運行效率。Python中的asyncio也是基於協程來進行實現的。在進入asyncio之前我們先來了解一下Python中怎麼通過生成器進行協程來實現並發。
example1
我們先來看一個簡單的例子來了解一下什麼是協程(coroutine),對生成器不了解的朋友建議先看一下Stackoverflow上面的這篇高票回答。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/271960.html