網路程式設計之 IO模型

2022-05-15 08:17:59 字數 4528 閱讀 7505

"""

我們這裡研究的io模型都是針對網路io的

* blocking io 阻塞io

* nonblocking io 非阻塞io

* io multiplexing io多路復用

* signal driven io 訊號驅動io

* asynchronous io 非同步io

由signal driven io(訊號驅動io)在實際中並不常用,所以主要介紹其餘四種io model。

"""#1)等待資料準備 (waiting for the data to be ready)

#2)將資料從核心拷貝到程序中(copying the data from the kernel to the process)

同步非同步

阻塞非阻塞

常見的網路阻塞狀態:

accept

recv

recvfrom

send雖然它也有io行為 但是不在我們的考慮範圍

io的底層其實是向作業系統要資料,沒有資料則等著

"""

我們之前寫的都是阻塞io模型 協程除外

"""import socket

server = socket.socket()

server.bind(('127.0.0.1',8080))

server.listen(5)

while true:

conn, addr = server.accept()

while true:

try:

data = conn.recv(1024)

if len(data) == 0:break

print(data)

conn.send(data.upper())

except connectionreseterror as e:

break

conn.close()

# 在服務端開設多程序或者多執行緒 程序池執行緒池 其實還是沒有解決io問題

該等的地方還是得等 沒有規避

只不過多個人等待的彼此互不干擾

將server.setblocking(false),沒有資料不等且捕獲異常,用for迴圈不斷的check

優點:規避了阻塞

缺點:大量占用cpu

"""

要自己實現乙個非阻塞io模型

"""import socket

import time

server = socket.socket()

server.bind(('127.0.0.1', 8081))

server.listen(5)

server.setblocking(false)

# 將所有的網路阻塞變為非阻塞

r_list =

del_list =

while true:

try:

conn, addr = server.accept()

except blockingioerror:

# time.sleep(0.1)

# print('列表的長度:',len(r_list))

# print('做其他事')

for conn in r_list:

try:

data = conn.recv(1024) # 沒有訊息 報錯

if len(data) == 0: # 客戶端斷開鏈結

conn.close() # 關閉conn

# 將無用的conn從r_list刪除

continue

conn.send(data.upper())

except blockingioerror:

continue

except connectionreseterror:

conn.close()

# 揮手無用的鏈結

for conn in del_list:

r_list.remove(conn)

del_list.clear()

# 客戶端

import socket

client = socket.socket()

client.connect(('127.0.0.1',8081))

while true:

client.send(b'hello world')

data = client.recv(1024)

print(data)

用select模組把不斷的check的操作交給作業系統來做,

"""

當監管的物件只有乙個的時候 其實io多路復用連阻塞io都比比不上!!!

但是io多路復用可以一次性監管很多個物件

server = socket.socket()

conn,addr = server.accept()

監管機制是作業系統本身就有的 如果你想要用該監管機制(select)

需要你匯入對應的select模組

"""import socket

import select

server = socket.socket()

server.bind(('127.0.0.1',8080))

server.listen(5)

server.setblocking(false)

read_list = [server]

while true:

r_list, w_list, x_list = select.select(read_list, , )

"""幫你監管

一旦有人來了 立刻給你返回對應的監管物件

"""# print(res) # (, , )

# print(server)

# print(r_list)

for i in r_list: #

"""針對不同的物件做不同的處理"""

if i is server:

conn, addr = i.accept()

# 也應該新增到監管的佇列中

else:

res = i.recv(1024)

if len(res) == 0:

i.close()

# 將無效的監管物件 移除

read_list.remove(i)

continue

print(res)

i.send(b'heiheiheiheihei')

# 客戶端

import socket

client = socket.socket()

client.connect(('127.0.0.1',8080))

while true:

client.send(b'hello world')

data = client.recv(1024)

print(data)

總結

"""

監管機制其實有很多

select機制 windows linux都有

poll機制 只在linux有 poll和select都可以監管多個物件 但是poll監管的數量更多

上述select和poll機制其實都不是很完美 當監管的物件特別多的時候

可能會出現 極其大的延時響應

epoll機制 只在linux有

它給每乙個監管物件都繫結乙個**機制

一旦有響應 **機制立刻發起提醒

針對不同的作業系統還需要考慮不同檢測機制 書寫**太多繁瑣

有乙個人能夠根據你跑的平台的不同自動幫你選擇對應的監管機制

selectors模組

"""

任務提交了之後程式做其他的事,當任務有結果時,會觸發**機制,轉而回來處理該資料

"""

非同步io模型是所有模型中效率最高的 也是使用最廣泛的

相關的模組和框架

模組:asyncio模組

非同步框架:sanic tronado twisted

速度快!!!

"""import threading

import asyncio

@asyncio.coroutine

def hello():

print('hello world %s'%threading.current_thread())

yield from asyncio.sleep(1) # 換成真正的io操作

print('hello world %s' % threading.current_thread())

loop = asyncio.get_event_loop()

tasks = [hello(),hello()]

loop.run_until_complete(asyncio.wait(tasks))

loop.close()

網路程式設計之IO模型

io多路復用概念 io發生時涉及的物件和步驟。對於乙個網路io,它會涉及到兩個系統物件,乙個是呼叫io的程序或者執行緒,另乙個就是系統核心。如當乙個read操作發生時,會先等待資料準備,然後將資料從核心拷貝到程序中去 阻塞io blocking io 特點 在執行io的兩個階段 等待資料和拷貝資料兩...

網路程式設計之IO模型 非同步IO

linux下的asynchronous io其實用得不多,從核心2.6版本才開始引入。先看一下它的流程 使用者程序發起read操作之後,立刻就可以開始去做其它的事。而另一方面,從kernel的角度,當它受到乙個asynchronous read之後,首先它會立刻返回,所以不會對使用者程序產生任何bl...

Linux網路程式設計之IO模型

同步是指乙個任務的完成需要依賴另外乙個任務時,只有等待被依賴的任務完成後,依賴的任務才能算完成。非同步是指不需要等待被依賴的任務完成,只是通知被依賴的任務要完成什麼工作,依賴的任務也立即執行,只要自己完成了整個任務就算完成了,非同步一般使用狀態 通知和 阻塞是指呼叫結果返回之前,當前執行緒會被掛起,...