gj12-1 协程和异步io
1 并發、并行、同步、異步、阻塞、非阻塞
并發、并行
并發是報一個時間段內有幾個程序在同一個cpu上運行,但是任意時刻只有一個程序在cpu上運行。在一個時間段內某一個請求很快,能夠響應的用戶就越多,高并發。
并行是指任意時刻點上,有多個程序同時運行在多個cpu上,并行數量跟CPU數一致的,因此沒有高并行。
情況:開水沒有:水壺要洗,茶壺茶杯要洗:火生了,茶葉也有了。怎么辦? 時間分配: 洗水壺:3 灌涼水:1 洗茶壺:3 洗茶杯:3 拿茶葉:1 泡茶:1 燒開水:30 并發版 老張 辦法甲:洗好水壺,灌上涼水,放在火上;在等待水開的時間里,洗茶壺、洗茶杯、拿茶葉;等水開了,泡茶喝。 總用時:3+1+30+1=35 辦法乙:先做好一些準備工作,洗水壺,洗茶壺茶杯,拿茶葉;一切就緒,灌水燒水;坐待水開了泡茶喝。 總用時:3+3+3+1+30+1=41 辦法丙:洗凈水壺,灌上涼水,放在火上,坐待水開;水開了之后,急急忙忙找茶葉,洗茶壺茶杯,泡茶喝。 總用時:3+1+30+3+3+1=41 并行版 老張:洗好水壺,灌上涼水,放在火上 老李:洗茶壺 老謝:洗茶杯 問題-喝茶同步、異步
同步是指代碼調用IO操作時,必須等待IO操作完成才返回的調用方式。
異步是指代碼調用IO操作時,不必等IO操作完成就返回的調用方式。
消息通信 的一種機制
阻塞、非阻塞
阻塞是指調用函數時候當前線程被掛起。
阻塞是指調用函數時候當前線程不會被掛起,而是立即返回。
是函數調用的一種機制
2 IO 多路復用 (select、poll 和 epoll)
C10K問題
C10k是一個在1999年被提出來的技術挑戰
如何在一顆 1GHz CPU,2G內存,1gbps網絡環境下,讓單臺服務器同時
為1萬個客戶端提供FTP服務
多用戶連接,多線程一個線程只能處理一個socket,不能處理上萬用戶,因為不可能開啟上萬線程。
Unix下五種I/O模型
阻塞式I/O
非阻塞式I/O
I/O復用
信號驅動式I/O(使用較少)
異步I/O(POSIX的aio系列函數)
阻塞式I/O
recvfrom 會一直阻塞,直到返回數據
client.setblocking(False) #socket 中設置非阻塞
client.connect((host,80))
非阻塞式I/O
沒有數據準備好就立馬返回
如果下一行代碼,依賴上一句(connect的建立)完成,就需要不斷的while循環去檢查狀態(是耗cpu的),時間和同步差不多。
如果下一行代碼,不依賴上一句代碼的執行完成,如做計算任務或者再次發起其他的連接請求,非阻塞IO就很有用
將數據從內核復制到用戶空間
I/O復用
I/O多路復用,很多框架用的
select 也是阻塞的,可以同時監聽多個文件句柄 socket 狀態。一旦有一個發生變化,就處理它,沒有去輪詢。 但 recvfrom 復制數據報,將數據從內核復制到用戶空間時仍需要耗費時間。
信號驅動式IO
用的比較少
異步IO
真正意義上的異步IO,
數據準備好了才發信號處理,省略了將數據從內核復制到用戶空間的等待時間,編程難度較大。對比io多路復用,性能提高不明顯
select、poll、epoll
? select,poll,epoll都是IO多路復用的機制。I/O多路復用就是通過一種機制,一個進程可以監視多個描述符,一旦某個描述符就緒(一般是讀就緒或者寫就緒),能夠通知程序進行相應的讀寫操作。但select,poll,epoll本質上都是同步I/O,因為他們都需要在讀寫事件就緒后自己負責進行讀寫,也就是說這個讀寫過程(將數據從內核復制到用戶空間)是阻塞的,而異步I/O則無需自己負責進行讀寫,異步I/O的實現會負責把數據從內核拷貝到用戶空間。
select
? select函數監視的文件描述符分3類,分別是writefds、readfds、和exceptfds。調用后select函數會阻塞,直到有描述副就緒(有數據可讀、可寫、或者有except),或者超時(timeout指定等待時間,如果立即返回設為null即可),函數返回。當select函數返回后,可以通過遍歷fdset,來找到就緒的描述符。select目前幾乎在所有的平臺上支持,其良好跨平臺支持也是它的一個優點。select的一個缺點在于單個進程能夠監視的文件描述符的數量存在最大限制,在Linux上一般為1024,可以通過修改宏定義甚至重新編譯內核的方式提升這一限制,但是這樣也會造成效率的降低。
poll
? 不同與select使用三個位圖來表示三個fdset的方式,poll使用一個pollfd的指針實現。
pollfd 結構包含了要監視的event和發生的event,不再使用select“參數-值”傳遞的方式。同時,pollfd并沒有最大數量限制(但是數量過大后性能也是會下降)。和select函數一樣,poll返回后,需要輪詢pollfd來獲取就緒的描述符。
? 從上面看,select和poll都需要在返回后,通過遍歷文件描述符來獲取已經就緒的socket。事實上,同時連接的大量客戶端在一時刻可能只有很少的處于就緒狀態,因此隨著監視的描述符數量的增長,其效率也會線性下降
epoll
? epol是在linux 2.6內核中提出的,是之前的 select 和 poll 的增強版本。相對于select和poll來說,epoll更加靈活,沒有描述符限制。epoll使用一個文件描述符管理多個描述符,將用戶關系的文件描述符的事件存放到內核的一個事件表中,這樣在用戶空間和內核空間的copy只需一次。? (nginx)
查詢利用了:紅黑樹
并不代表 epoll 比 select 一定好
# 1. epoll 并不代表一定比 select 好
# 在并發高的情況下,連接活躍度不是很高, epoll 比 select
# 并發性不高,同時連接很活躍, select 比 epoll好
總結
以上是生活随笔為你收集整理的gj12-1 协程和异步io的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: gj10 python socket编程
- 下一篇: gj12-2 协程和异步io