zoukankan      html  css  js  c++  java
  • IO模型

    IO模型

    详细内容参考: https://www.cnblogs.com/Dominic-Ji/articles/10929396.html

    IO模型简介

    """
    我们这里研究的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。
    """
    #1)等待数据准备 (Waiting for the data to be ready)
    #2)将数据从内核拷贝到进程中(Copying the data from the kernel to the process)
    
    同步异步
    阻塞非阻塞
    常见的网络阻塞状态:
        accept
        recv
        recvfrom
        send虽然它也有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

    
    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()
            r_list.append(conn)
        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删除
                        del_list.append(conn)
                        continue
                    conn.send(data.upper())
                except BlockingIOError:
                    continue
                except ConnectionResetError:
                    conn.close()
                    del_list.append(conn)
            # 挥手无用的链接
            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)
    

    总结

    """
    虽然非阻塞IO给你的感觉非常的牛逼
    但是该模型会	长时间占用着CPU并且不干活 让CPU不停的空转
    我们实际应用中也不会考虑使用非阻塞IO模型
    """
    

    IO多路复用

    """
    当监管的对象只有一个的时候 其实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)  # ([<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080)>], [], [])
        # print(server)
        # print(r_list)
        for i in r_list:  #
            """针对不同的对象做不同的处理"""
            if i is server:
                conn, addr = i.accept()
                # 也应该添加到监管的队列中
                read_list.append(conn)
            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

    """
    异步IO模型是所有模型中效率最高的 也是使用最广泛的
    相关的模块和框架
    	模块:asyncio模块
    	异步框架:sanic tronado twisted
    		速度快!!!
    """
    import threading
    import asyncio
    
    #3.5之前
    @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()
    
    
    #新版本asyncio用法
    import asyncio
    
    async def main():
        print('Hello ...')
        await asyncio.sleep(1)
        print('... World!')
    
    # Python 3.7+
    asyncio.run(main())
    

    四个IO模型对比

  • 相关阅读:
    RN-Android构建失败:Caused by: org.gradle.api.ProjectConfigurationException: A problem occurred configuring root project 'AwesomeProject'.
    Android更新包下载成功后不出现安装界面
    真机调试: The application could not be installed: INSTALL_FAILED_TEST_ONLY
    react native 屏幕尺寸转换
    Android Studio生成签名文件,自动签名,以及获取SHA1和MD5值
    React Native安卓真机调试
    git提交代码报错Permission denied, please try again
    The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.
    命令行设置快捷命令
    Linux 常用指令
  • 原文地址:https://www.cnblogs.com/chenwenyin/p/12793404.html
Copyright © 2011-2022 走看看