阻塞IO和非阻塞IO的區別與io多路復用


讀:

  在阻塞條件下,如果沒有發現數據在網絡緩沖中會一直等待,當發現有數據的時候會把數據讀到用戶指定的緩沖區。但是如果這個時候讀到的數據量比較少,比參數中指定的長度要小,
read並不會一直等待下去,而是立刻返回。read的原則是數據在不超過指定的長度的時候有多少讀多少,沒有數據就會一直等待。所以一般情況下我們讀取數據都需要采用循環讀的方式讀取數據,
一次read完畢不能保證讀到我們需要長度的數據,read完一次需要判斷讀到的數據長度再決定是否還需要再次讀取。  在非阻塞的情況下,read的行為是如果發現沒有數據就直接返回,如果發現有數據那么也是采用有多少讀多少的進行處理.對於讀而言,阻塞和非阻塞的區別在於沒有數據到達的時候是否立刻返回。

寫:

  在阻塞的情況,是會一直等待直到write完全部的數據再返回。
  非阻塞寫的情況,是采用可以寫多少就寫多少的策略。

 

io多路復用

# 在並發高的情況下,連接活躍度不是很高, epoll比select
# 並發性不高,同時連接很活躍, select比epoll好

#通過非阻塞io實現http請求

import socket
from urllib.parse import urlparse


#使用非阻塞io完成http請求

def get_url(url):
    #通過socket請求html
    url = urlparse(url)
    host = url.netloc
    path = url.path
    if path == "":
        path = "/"

    #建立socket連接
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.setblocking(False)
    try:
        client.connect((host, 80)) #阻塞不會消耗cpu
    except BlockingIOError as e:
        pass

    #不停的詢問連接是否建立好, 需要while循環不停的去檢查狀態
    #做計算任務或者再次發起其他的連接請求

    while True:
        try:
            client.send("GET {} HTTP/1.1\r\nHost:{}\r\nConnection:close\r\n\r\n".format(path, host).encode("utf8"))
            break
        except OSError as e:
            pass


    data = b""
    while True:
        try:
            d = client.recv(1024)
        except BlockingIOError as e:
            continue
        if d:
            data += d
        else:
            break

    data = data.decode("utf8")
    html_data = data.split("\r\n\r\n")[1]
    print(html_data)
    client.close()

if __name__ == "__main__":
    get_url("http://www.baidu.com")

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM