多路復用的分析例項:服務端、客戶端
#服務端配置
from socket import *
import
time
import
select
server =socket(af_inet, sock_stream)
server.bind((
'127.0.0.1
',8080))
server.listen(5)
server.setblocking(false)
'''select/epoll的優勢並不是對於單個連線能處理得更快,而是在於能處理更多的連線。
當任何乙個socket中的資料準備好了,select就會返回,會從作業系統將資料拷貝到應用程式中
1.select.select(read_list,write_list,,5)是由應用程式發起的,傳送給作業系統,讓作業系統去找有資料的套接字socket
5:可以不用寫,意思是5秒如果有資料連線進來會執行,如果沒有回執行下一行**(不用寫是因為如果沒資料執行下面的也沒意義,
能執行下面的**,肯定是上面有資料過來已經成功建立了連線)
重點:是沒有資料過來才阻塞
有資料過來會一直執行,不會阻塞
2.非同步io:
傳送之後不用管,會自動把結果發給你,發乙個給作業系統就不用管了(用於爬蟲,效率最高)
'''data_dic={} #
設定乙個空字典,目的是用於將conn:data 一一繫結
read_list=[server,] #
放和收訊息有關的套接字 conn.recv() server.accept(),是被檢測的一些套接字
write_list= #
send寫資料,存放建立好的一些套接字服務端
print('
start....')
while
true:
#select執行的返回結果是維護的列表裡面,哪個有資料過來了
rl,wl,xl=select.select(read_list,write_list,)
#這裡select在指定的時間段內不停的去問作業系統要資料,如果沒有資料就會執行下面一行**
print(read_list) #
read_list=[server,conn1,conn2,conn3,conn4]
print(rl,len(rl)) #
重點理解:上面迴圈每次得到r1隻時包換作業系統詢問到的有資料的套接字[conn1,conn2..]
#r1就是select返回的有
#print('read_list:%s rl:%s wl:%s ' %(len(read_list),len(rl),len(wl))) #rl=[conn1,conn2]
#注意:
#1.剛開始迴圈r1裡面只有server,read_list=[server]裡面也只有server,此時r1和read_list裡面內筒一樣
#2.剛開始read_list=[server,conn] server是負責建立新連線的,conn是負責收訊息的
#3.當服務端accept()收到新的連線並加入到read_list[server,conn]裡面,
#問到結果之後此時 rl,wl,xl=select.select(read_list,write_list,),得到的r1裡麵只包含已經有資料過來的連線
#read_list裡面的連線請求不會取走,只要有資料就不會阻塞,阻塞的情況是列表裡面沒有資料拿
#r1裡面去依次for迴圈取資料,如果是server套接字物件就是accept(),否則就負責recv()資料
for sk in rl: #
初始狀態read_list裡面放的的是server套接字,需要執行accept操作
if sk == server: #
判斷for迴圈,首先只有server服務端負責accept()接收
conn,addr=sk.accept()
#後面併發的數量多了時要往read_list裡面放一些有資料的套接字物件
else
:
#sk.recv(1024)
#print(sk)
data=sk.recv(1024)
#有訊息往外回所以加進去了
data_dic[sk]=data #
製作字典繫結send的物件和資料:格式為傳送的物件conn:對應傳送的資料 data
#因為conn占用了應用程式的資源、對應作業系統還有維持連線
for sk in
wl: sk.send(data_dic[sk].upper())
#根據字典裡面對應的socket套接字物件拿到,拿到
data_dic.pop(sk) #
發完之後字典裡面就沒必要存放訊息了,所以就**
write_list.remove(sk) #
回完之後沒有了,所以就刪除
#write_list還沒滿的情況下會返回w1
#read_list佔應用程式的資源
#因為conn占用了應用程式的資源、對應作業系統還要維持鏈結
#客戶端配置
from socket import *
import
osclient=socket(af_inet,sock_stream)
client.connect((
'127.0.0.1
',8080))
while
true:
msg=input('
輸入要操作的命令:')
client.send(msg.encode(
'utf-8'))
data=client.recv(1024)
print(data.decode('
utf-8
'))
python io多路復用
用for迴圈執行多使用者訪問 sever import socket sk1 socket.socket sk1.bind 127.0.0.1 888 sk1.listen import select ipt sk1,output message dic eer while true r list,...
python IO多路復用,select模組
觸發機制 1 水平觸發 2 邊緣觸發 io多路復用單執行緒實現併發,實現模組 1 select 效率最低 2 poll 3 epoll 最好,nginx的實現 linux下有這3種模組,windows下只有select模組 io多路復用的好處 同時可以監聽多個連線 io多路復用的select模組觸發...
Linux IO多路復用
一.select 函式 include include include int select int n,fd set readfds,fd set writefds,fd set exceptfds,struct timeval timeout fd clr int fd,fd set set f...