• IO模型、复习网络和并发知识点



    ###IO模型简介

    ```python
    """
    我们这里研究的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模型

    ```python
    """
    我们之前写的都是阻塞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问题
    该等的地方还是得等 没有规避
    只不过多个人等待的彼此互不干扰
    ```

    ### 非阻塞IO

    ```python
    """
    要自己实现一个非阻塞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)
    ```

    **总结**

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

    任何的技术点都有它存在的意义
    实际应用或者是思想借鉴
    """
    ```

    ### IO多路复用

    ```python
    """
    当监管的对象只有一个的时候 其实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)
    ```

    **总结**

    ```python
    """
    监管机制其实有很多
    select机制 windows linux都有

    poll机制 只在linux有 poll和select都可以监管多个对象 但是poll监管的数量更多

    上述select和poll机制其实都不是很完美 当监管的对象特别多的时候
    可能会出现 极其大的延时响应

    epoll机制 只在linux有
    它给每一个监管对象都绑定一个回调机制
    一旦有响应 回调机制立刻发起提醒

    针对不同的操作系统还需要考虑不同检测机制 书写代码太多繁琐
    有一个人能够根据你跑的平台的不同自动帮你选择对应的监管机制
    selectors模块
    """
    ```

    ### 异步IO

    ```python
    """
    异步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模型对比

    参考博客园图解,稍微了解即可


    # 网络并发知识点梳理

    * 软件开发架构

    * 互联网协议

    ```python
    """
    osi七层
    五层
    每一层都是干嘛的
    以太网协议 广播风暴
    IP协议

    TCP/UDP
    """
    ```

    * 三次握手四次挥手

    * socket简介

    * TCP黏包问题 定制固定长度的报头

    * UDP协议

    * socketserver模块


    * 操作系统发展史
    * 多道技术
    * 进程理论
    * 开启进程的两种方式
    * 互斥锁
    * 生产者消费者模型
    * 线程理论
    * 开启线程的两种方式
    * GIL全局解释器锁
    * 进程池线程池
    * 协程的概念
    * IO模型的了解
  • 相关阅读:
    EXTJS 动态改变Gird 列值
    EXTJS动态改变store的proxy的params
    获取Spring容器Bean
    EXTJS 6 必填项加星号*
    Maven打包附加配置文件
    MyEclipse 优化
    Android-SurfaceView生命周期
    Android-PopupWindow
    Android-Sqlite3的使用
    Android-adb的使用
  • 原文地址:https://www.cnblogs.com/0B0S/p/12793517.html
Copyright © 2020-2023  润新知