Python之非同步IO模型實現socket併發

2021-09-19 10:27:19 字數 1933 閱讀 6320

服務端:

import socket

sk = socket.socket()

addr = ('127.0.0.1',8090)

sk.bind(addr)

sk.listen()

sk.setblocking(false) # 設定非阻塞模式,accept,recv等方法均不阻塞,而是丟擲異常

conn_lst = # 建立乙個列表儲存接收到的連線

del_lst = # 建立乙個列表儲存已經關閉的連線

while true:

try:

conn,addr_client = sk.accept() # 沒有連線時--blockingioerror

print('接收到乙個連線') # 如果上一步沒有異常發生,則表示收到乙個連線

except blockingioerror:

for conn in conn_lst: # 迴圈接收到的連線,嘗試接收訊息

try:

msg = conn.recv(1024) # 如果沒有收到,同樣丟擲異常--blockingioerror

if not msg: # 從乙個關閉的客戶端接收訊息,收到的值為空

continue

print(msg)

except blockingioerror:

for conn in del_lst: # 將客戶端已關閉的連線關閉**

conn.close()

conn_lst.remove(conn)

del_lst.clear() # 清空已關閉的連線記錄

客戶端:

import socket

from threading import thread

import time

def client():

sk = socket.socket()

addr = ('127.0.0.1',8090)

sk.connect(addr)

sk.send(b'hell0')

sk.close()

if __name__ == '__main__': # 模擬20個客戶端併發連線服務端

for i in range(20):

thread(target=client).start()

弊端:while true迴圈模式極耗cpu,通常需要在迴圈中加入sleep,但是加入sleep影響實時性

io多路復用模型-服務端

# 鑑於非同步io模型while true不停掃瞄高消耗cpu,所以採用io多路復用模型

import select

import socket

sk = socket.socket()

addr = ('127.0.0.1',8090)

sk.setblocking(false)

sk.bind(addr)

sk.listen()

read_lst = [sk]

while true:

# select 監聽請求物件,如果沒有收到請求,則阻塞,此處相當於監聽accept事件

rret,wret,xret = select.select(read_lst,,) # rret為響應事件物件,若響應accept事件,則返回sk,若響應recv,則返回conn

# print(rret)

for i in rret:

if i is sk:

conn,addr = i.accept()

else:

msg = i.recv(1024)

if not msg:

read_lst.remove(i)

i.close()

continue

print(msg)

python之非同步IO

我們知道,cpu的速度遠遠快於磁碟 網路等io。在乙個執行緒中,cpu執行 的速度極快,然而,一旦遇到io操作,如讀寫檔案 傳送網路資料時,就需要等待io操作完成,才能繼續進行下一步操作。這種情況稱為同步io。在io操作的過程中,當前執行緒被掛起,而其他需要cpu執行的 就無法被當前執行緒執行了。因...

C 非同步I O模型

using system using system.collections.generic using system.io using system.net using system.net.sockets using system.threading using linfx.net using l...

非同步通知IO模型

同步非同步的關鍵是函式的呼叫時刻和返回時刻與資料傳輸的開始時刻和完成時刻,資料傳輸指輸出或輸入到緩衝。非同步通知io模型 通知io指發生了io相關操作,通知輸入緩衝有資料需要讀取,輸出緩衝無資料可以寫入。select方式是典型的通知io模型,select方式一般是同步通知,select返回時說明有i...