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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python网络编程:IO多路复用

發布時間:2025/7/14 python 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python网络编程:IO多路复用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

io多路復用:可以監聽多個文件描述符(socket對象)(文件句柄),一旦文件句柄出現變化,即可感知。

1 sk1 = socket.socket() 2 sk1.bind(('127.0.0.1',8001)) 3 sk1.listen() 4 5 # sk2 = socket.socket() 6 # sk2.bind(('127.0.0.1',8002)) 7 # sk2.listen() 8 while True: 9 conn,address = sk.accept()#阻塞等待客戶端連接、連接、客戶端地址信息 10 print(conn,address) 11 conn.sendall(bytes('北京歡迎你',encoding='utf-8')) 12 while True: 13 ret_bytes = conn.recv(1024) 14 ret_str = str(ret_bytes,encoding='utf-8') 15 if ret_str == 'q': 16 break 17 conn.sendall(bytes(ret_str+'好',encoding='utf-8')) 18 print(address,conn) 19

sk1\sk2就叫作文件描述符、文件句柄。上面的程序只能執行sk1。

IO多路復用有一種機制,可以接受多個文件描述符,一旦有誰變化了,就處理。

1 import socket 2 sk1 = socket.socket() 3 sk1.bind(('127.0.0.1',8001)) 4 sk1.listen() 5 6 sk2 = socket.socket() 7 sk2.bind(('127.0.0.1',8002)) 8 sk2.listen() 9 10 sk3 = socket.socket() 11 sk3.bind(('127.0.0.1',8002)) 12 sk3.listen() 13 14 inputs = [sk1,sk2] 15 #本例是用select偽裝成多處理用戶連接請求,比socket的好處在于不用等待? 難點在于inputs里兩類socket,客戶端socket和服務端socket? 16 import select 17 while True: 18 #[sk1,sk2,],select內部自動監聽sk1,sk2,sk3三個對象,一旦某個句柄發生變化,就會將其放到r_list里。第一次發生變化是sk.accept(),即有人來連sk1.則r_list = [sk1] 19 r_list,w_list,e_list = select.select(inputs,outputs,inputs,1)#等一秒看是否有人來連接,沒有的話執行下一次循環。最多等待的時間。 20 print('正在監聽的socket對象%d' % len(inputs)) 21 print(r_list) 22 for sk1_or_conn in r_list: 23

IO多路復用是操作系統底層提供的功能,我們只是用Python去調用它,分三種方式,select,poll,epoll。windows只支持select.

select底層實現原理:

系統內部c語言進行for循環檢測,當文件句柄發送變化的時候告訴我們。性能較低,并且只支持最多1024個文件描述符。


所以后來就有了poll,對于文件描述符個數沒限制了,但底層也是用for循環實現的。

之后又出現了epoll,底層就不用for循環了,而是用異步實現的,把句柄都放進去,誰有變化了誰主動告訴epoll,而不是for循環一遍遍監測。所以epoll的性能是最高的。

Nginx的內部就是socket結合epoll來監聽用戶請求的。

for sk in e_list:? #e_list是發生錯誤的文件描述符列表

??? inputs.remove(sk)


1 import socket 2 sk1 = socket.socket() 3 sk1.bind(('127.0.0.1',8001)) 4 sk1.listen() 5 6 # sk2 = socket.socket() 7 # sk2.bind(('127.0.0.1',8002)) 8 # sk2.listen() 9 # 10 # sk3 = socket.socket() 11 # sk3.bind(('127.0.0.1',8003)) 12 # sk3.listen() 13 inputs = [sk1] 14 outputs = [] 15 #本例是用select偽裝成多處理用戶連接請求,比socket的好處在于不用等待? 難點在于inputs里兩類socket,客戶端socket和服務端socket。 16 import select 17 while True: 18 #[sk1,sk2,],select內部自動監聽sk1,sk2,sk3三個對象,一旦某個句柄發生變化 19 r_list,w_list,e_list = select.select(inputs,outputs,inputs,1) 20 print('正在監聽的socket對象%d' % len(inputs)) 21 print(r_list) 22 for sk1_or_conn in r_list: 23 #每一個連接對象 24 if sk1_or_conn == sk1: 25 #表示有新用戶來連接 26 conn, address = sk1_or_conn.accept() 27 inputs.append(conn) 28 else: 29 #有老用戶發消息了 30 try: 31 data_bytes = sk1_or_conn.recv(1024) 32 except Exception as ex: 33 #如果用戶中斷連接 34 inputs.remove(sk1_or_conn) 35 else: 36 #用戶正常發消息 37 # data_str = str(data_bytes,encoding='utf-8') 38 # sk1_or_conn.sendall(bytes(data_str+'好',encoding = 'utf-8')) 39 outputs.append(sk1_or_conn) 40 #w_list僅僅存誰給我發過消息,如果想讀寫分離就會用到這個參數 41 for conn in w_list: 42 conn.sendall(bytes('hello',encoding='utf-8')) 43 outputs.remove(conn) 44 IO多路復用處理多用戶請求

上面的難點在于要理解r_list其實并不等于inputs.

inputs里面兩類數據,一類是服務端的socket sk1,另一類是客戶端的socket(只要有人來連接就apend一個socket對象)

而r_list里面存的是發生變化的對象,多個用戶來連sk1,r_list里就是sk1,而有用戶發消息,那r_list里就變為發消息的socket對象其。


socketserver:
select/epoll + socket +多線程實現并發操作。

轉載于:https://www.cnblogs.com/bolenzhang/p/7197898.html

總結

以上是生活随笔為你收集整理的Python网络编程:IO多路复用的全部內容,希望文章能夠幫你解決所遇到的問題。

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