zoukankan      html  css  js  c++  java
  • 并发编程5

    IO模型

    五种IO模型
       * blocking IO           阻塞IO
        * nonblocking IO      非阻塞IO
        * IO multiplexing      IO多路复用
       * signal driven IO     信号驱动IO
        * asynchronous IO    异步IO
        由signal driven IO(信号驱动IO)在实际中并不常用,所以主要介绍其余四种IO Model。
       同步异步
    阻塞非阻塞
    常见的网络阻塞状态:
    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问题
    该等的地方还是得等 没有规避
    只不过多个人等待的彼此互不干扰
    '''
    非阻塞型IO

    如何自己实现非阻塞型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)

    PS:虽然非阻塞IO给人的感觉非常顺滑~,但是非阻塞型IO会长时间占用CPU,使得CPU不停的空转,因此在实际应用中也不会使用到非阻塞型IO

    IO多路复用
    '''
    IO多路复用,听名字就知道肯定是多个对象。
    在监管一个对象时IO多路复用甚至连阻塞IO都不如
    但时IO多路复用可以监管多个对象
    监管机制是操作系统本身就有的 如果你想要用该监管机制(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)

    PS:在不同的平台有不同的监管机制,相对的监管数量也有差异

    但是selectors模块可以根据你程序运行的不同平台帮你选择对应的监管机制

    异步IO
    '''
    异步IO是所有所有模型中效率最高,并且是应用最广泛的一种
    模块与框架——asyncio模块
    ——sanic tronado twisted异步框架
    '''
    asyncio模块
    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()

  • 相关阅读:
    Gradle中使用SpringBoot插件构建多模块遇到的问题
    使用docker-compose快速构建集群示例(一)
    tensorflow对多维tensor按照指定索引重排序
    tensorflow Dataset及TFRecord一些要点【持续更新】
    RNN、LSTM介绍以及梯度消失问题讲解
    使用BERT模型生成句子序列向量
    给定数字N,输出小于10^N的所有整数
    使用BERT模型生成token级向量
    使用BERT预训练模型+微调进行文本分类
    tensorflow与神经网络中遇到的问题与解决方法【持续更新】
  • 原文地址:https://www.cnblogs.com/bailongcaptain/p/12794807.html
Copyright © 2011-2022 走看看