日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

说说基于网络的五种IO模型

發布時間:2023/12/20 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 说说基于网络的五种IO模型 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  

# django不是一個異步框架 # tornado是異步的web框架# 處理每秒大量的請求# 個人理解的IO:就是應用層與內核驅動層的交互,這個過程無論從應用層到內核中,還是驅動層等待硬件層的數據,都是需要時間的,這個過程是IO操作過程# 五種IO Model# blocking IO 阻塞IO# nonblocking 非阻塞IO# IO multiplexing IO多路復用# signal driven IO 信號驅動IO# asynchronous IO 異步IO# 在python中沒有提供異步IO的機制,沒有操作系統將數據直接給應用層的獲取到數據的接口. 但是由很多python的異步框架# 這種異步IO機制其實是很好的 # IO發生時涉及的對象和步驟,對于一個network IO,我們以read舉例,他會涉及到兩個系統對象,一個是調用這個IO的process(or thread),另一個就是系統內核。當一個read操作時,該操作會經歷兩個階段# 1.等待數據準備# 2.將數據從內核拷貝到應用層

# 同步 提交一個任務之后要等待這個任務執行完畢才能繼續執行其他的 # 異步 只管提交任務,不用等待該任務執行完畢就可以繼續做其他事情 # 阻塞 運行狀態 -> 阻塞狀態 -> 就緒狀態 -> 運行狀態、一進程或線程阻塞則會進入阻塞狀態休眠 # 非阻塞

  1.非阻塞IO

# 非阻塞IO # import socket # sk = socket.socket() # sk.setblocking(False) # 設置非阻塞 # sk.bind(('127.0.0.1', 8080)) # sk.listen() # # try: # conn, addr = sk.accept() # 因為將套接字設置為了非阻塞,所以這里會報錯,因為accept不允許為非阻塞性的,所以下面捕捉異常,有異常則直接pass # print('有客戶端連接上來 ') # except BlockingIOError: # pass

  2.阻塞IO

  3.IO多路復用

# 在windows、linux上,有一個select專門提供IO多路復用的。# poll機制 # linux上有# epoll機制 # linux上有# poll機制和epoll機制使用方法和select一樣# poll可以監聽的對象比select可以監聽的多。如果select能監聽500,則poll能監聽1000個類似這樣# poll和select都是操作系統去輪詢機制的監聽被監聽的項,看是否有讀操作等,隨著監聽列表增多,會導致效率變差# epoll機制# 給每一個被監聽的對象都綁定了一個回調函數,當被監聽的對象有監聽事件后,會觸發此監聽對象綁定的回調函數這種機制比select和poll的輪詢效率要高,高并發非常有用# import selectors 這個模塊會幫助你選擇當前操作系統上最優的IO多路復用

  3.1 IO多路復用中的select

  服務端

import select # 內置的select模塊,用于IO多路復用 import socket # select.select(rlist, wlist, xlist, timeout=None)# 參數是3個列表,一個監聽超時時間# rlist參數,表示監聽讀,直到監聽到讀或超時返回# wlist參數,表示監聽寫,直到監聽到寫或超時返回# xlist參數,表示監聽條件# timeout參數,監聽超時時間# 返回值有三個 sk = socket.socket() sk.bind(('127.0.0.1', 8080)) sk.setblocking(False) # 設置為非阻塞 sk.listen()read_lst = [sk] # 創建一個列表,想要監聽誰,則將哪個對象放進來,這里開始先監聽socket對象,當有人向這個socket發起連接的時候,select則會監聽到返回一個socket while 1:# 調用select后操作系統會幫你監聽三個監聽列表,這里監聽的是監聽讀列表r_lst, w_lst, x_lst = select.select(read_lst, [], []) # 當監聽到后,返回一個元組,元組中有三個元素,分別是rlist,wlist,xlist。這里rlist中最開始監聽sk,因此當有客戶端連接上來后,會監聽有要被讀的事件,這里會返回得到一個r_lst,r_lst中有一個sk對象#print(r_lst)for i in r_lst:if i is sk: # 判斷監聽到的對象是否是sk對象conn, addr = i.accept() # 此時直接sk.accpet()就會得到客戶端連接和地址read_lst.append(conn) # 將客戶端連接符加入到監聽列表中else: # 如果監聽到的不是sk對象, 這里的第二可能是監聽到了客戶端連接符有要被讀的事件msg = i.recv(1024)if msg == b'': # 當客戶端連接關閉時,會接收到空的數據,i.close() # 因為客戶端連接主動關閉,這里也要關閉下這個客戶端連接read_lst.remove(i) # 同時在監聽列表中去除這個客戶端連接符,不再去監聽它continueprint(msg)

  3.2 linux上更好的IO多路復用epoll、selectors選擇當前系統最優的IO多路復用機制

  服務端

# linux上的selectors IO多路復用機制,IO多路復用機制,默認選擇系統最優,linux上肯定選擇epoll import selectors from socket import *def read(conn, mask):'''將來要綁定的回調函數:param conn::param mask::return:'''try:data = conn.recv(1024)if not data: # 如果監聽客戶端的數據是空數據,則表示客戶端連接關閉了print('closeing', conn)sel.unregister(conn) # 在監聽列表中去除這個客戶端連接的監聽conn.close() # 同時服務端也關閉這個客戶端連接描述符returnconn.send(data.upper() + b'SB')except Exception: # 該客戶端連接描述符監聽到異常事件,則直接關閉客戶端連接print('closing', conn)sel.unregister(conn) # 在監聽列表中去除這個客戶端連接的監聽conn.close() # 同時服務端也關閉這個客戶端連接描述符def accept(server_fileobj, mask):''':param server_fileobj: 接收到的socket:param mask::return:'''conn, addr = server_fileobj.accpet() # 得到客戶端連接描述符sel.register(conn, selectors.EVENT_READ, read) # 將conn客戶端連接符注冊到監聽列表中,監聽的是其讀時間,綁定的回調函數是readif __name__ == '__main':sk = socket()sk.setblocking(SOL_SOCKET, SO_REUSEPORT, 1)sk.bind(('127.0.0.1', 8080))sk.listen(5)sk.setblocking(False)sel = selectors.DefaultSelector() # 獲取到當前操作系統最優的IO多路復用機制sel.register(sk, selectors.EVENT_READ, accept) # 將socket對象注冊到監聽列表中,監聽其讀事件,當有讀事件時綁定的回調函數accpet會被執行# server_fileobj = socket(AF_INET, SOCK_STREAM)# server_fileobj.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)# server_fileobj.bind(('127.0.0.1', 8080))# server_fileobj.listen(5)# server_fileobj.setblocking(False)# sel.register(server_fileobj, selectors.EVENT_READ, accept)while True:events = sel.select() # 檢測到所有的fileobj(監聽列表中的所有對象,都是文件描述符),是否有完成wait data階段。當監聽到有事件時返回for sel_obj, mask in events:callback = sel_obj.data # 第一次是callback = accpet 通過sel_obj.data就能拿到剛剛這個被監聽對象的回調函數callback(sel_obj.fileobj, mask) # 第一次是ccpet(server_fileobj, 1) 直接調用回調函數

  客戶端

import socket from threading import Threaddef func():sk = socket.socket()sk.connect(('127.0.0.1', 8080))sk.send(b'hello')sk.close()if __name__ == '__main__':for i in range(20):Thread(target=func).start()

  4.信號驅動IO

  5.異步IO

?

 6.五種IO模型的比較,個人覺得肯定還是異步IO好

轉載于:https://www.cnblogs.com/whylinux/p/9867149.html

總結

以上是生活随笔為你收集整理的说说基于网络的五种IO模型的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。