zoukankan      html  css  js  c++  java
  • day42 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()
    
  • 相关阅读:
    放一个Dynamicinputs corresponding to Dynamicknobs的Node源码
    NDK学习笔记(四):OutputContext机制
    NDK学习笔记(三):DynamicKnobs的机制
    OpenEXR的采样机制
    OpenEXR的读取机制
    OpenEXR的输出机制
    虚拟机中安装centOS及破解nuke的方法
    OpenEXR-2.2.0在Win7 x64系统下的安装方法
    NDK学习笔记(二)
    NDK学习笔记(Add.cpp注释)(一)
  • 原文地址:https://www.cnblogs.com/hz2lxt/p/12795672.html
Copyright © 2011-2022 走看看