day41 io模型

一、io模型简介

Stevens在文章中一共比较了五种IO Model:

  • blocking IO 阻塞IO

  • nonblocking IO 非阻塞IO

  • IO multiplexing IO多路复用
  • signal driven IO 信号驱动IO
  • asynchronous IO 异步IO
    由signal driven IO(信号驱动IO)在实际中并不常用,所以主要介绍其余四种IO Model。

img

常见的网络阻塞状态:accept,recv

二、阻塞io阻塞IO模型图.png

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

非阻塞IO模型图.png

服务端

import socket

sever = socket.socket()
sever.bind(('127.0.0.1',8080))
sever.listen(5)
sever.setblocking(False)
# 把服务端中的io延迟都改成非阻塞态,直接运行后面的代码
# 原来的io是为了防止报错,让我们停住,现在改成非阻塞了,就要在每一个io前抓取错误
r_list = []
del_list = []
while True:
    try:
        conn,addr = sever.accept()
        r_list.append(conn)
    except BlockingIOError:
        for conn in r_list:
            try:
                data = conn.recv(1024)
                if len(data) == 0:
                    del_list.append(conn)
                    conn.close()
                    continue
                conn.send(data.upper())
            except BlockingIOError:
                continue
            except ConnectionResetError:
                del_list.append(conn)
                conn.close()
        for conn in del_list:
            r_list.remove(conn)
        del_list.clear()

        客户端
import socket

s = socket.socket()
s.connect(('127.0.0.1',8080))

while True:
    s.send('hz is nb'.encode('utf-8'))
    data = s.recv(1024)
    print(data)

四、io多路复用

img

io多路复用本质上是操作系统帮我们监测任务的返回值,我们同样要把程序中的阻塞态改成非阻塞态。

在监管对象只有一个的时候,他的效率还没有阻塞io快,用于多个对象运行。

服务端

import socket
import select

s = socket.socket()
s.bind(('127.0.0.1',8082))
s.listen(5)
s.setblocking(False)
r_list = [s]


while True:
    r, w, x = select.select(r_list, [], [])
    # 通过select帮我们监测对象的执行
    for i in r:
        # 不同的对象执行不同的代码
        if i is s:
            conn,addr = i.accept()
            r_list.append(conn)
        else:
            try:
                data = i.recv(1024)
                if len(data) == 0:
                    i.close()
                    r_list.remove(i)
                    continue
                i.send(data.upper())
            except ConnectionResetError:
                i.close()
                r_list.remove(i)
  客户端
import socket

c = socket.socket()
c.connect(('127.0.0.1',8082))
while True:
    c.send(b'hz is nb')
    data = c.recv(1024)
    print(data)

五、异步io

img

"""
异步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()

猜你喜欢

转载自www.cnblogs.com/hz2lxt/p/12795672.html