zoukankan      html  css  js  c++  java
  • I/O多路复用

    I/O多路复用
    # 同步:提交一个任务之后要等待这个任务执行完毕
    #
    # 异步:只管提交任务,不等待这个任务执行完毕就可以去做其他的事情
    #
    # 阻塞:recv、recvfrom、accept,线程阶段  运行状态-->阻塞状态-->就绪
    #
    # 非阻塞:没有阻塞状态
    # 对于服务端在recv和send,accetpt的时候都会处于阻塞的状态,这导致了线程服务执行或者是
    # 计算任何的网络请求
    # low版解决方案:
    # 在服务端使用多线程或者是多进程的方式,让每个连接都有自己的线程或者是进程
    # 存在问题: 如果线路过多的时候,会严重占用系统资源,减低系统对外界的响应效率,且他们本生也存在假死的状态
    #
    # 改进方案》
    # “线程池”旨在减少创建和销毁线程的频率,其维持一定合理数量的线程,并让空闲的线程重新承担新的执行任务。“连接池”维持连接的缓存池
    # ,尽量重用已有的连接、减少创建和关闭连接的频率。
    # 这两种技术都可以很好的降低系统开销,都被广泛应用很多大型系统,如websphere、tomcat和各种数据库等
    
    # 改进方案后存在的问题》》
    # 面临的可能同时出现的上千甚至上万次的客户端请求,“线程池”或“连接池”或许可以缓解部分压力,但是不能解决所有问题。
    # 总之,多线程模型可以方便高效的解决小规模的服务请求,
    # 但面对大规模的服务请求,多线程模型也会遇到瓶颈,可以用非阻塞接口来尝试解决这个问题(不推荐使用)

    1.2非阻塞(不推荐)
    import socket
    import time
    server = socket.socket()
    ip = ('127.0.0.1',8080)
    server.bind(ip)
    server.listen()
    
    server.setblocking(False)
    connlist = []
    while 1:
        while 1:
            try:
                con,add = server.accept()#设置为非阻塞的时候,如果没有人连接的直接报错,
                connlist.append(con)
                break
            except Exception:
                print('没有人连接我')
                time.sleep(0.1) #减少CPU的消耗
        for con in connlist:
            while 1:
                try:
                    msg = con.recv(1024).decode('utf-8')
                    print(msg)
                    hh = 'qingshur '.encode('utf-8')
                    con.send(hh)
                    break
                except Exception:
                    print('么有消息')
    非阻塞服务端
    
    
    import socket
    client = socket.socket()
    client.connect(('127.0.0.1',8080))
    while 1:
        to_ser = input('我想说>>>>>').encode('utf-8')
        client.send(to_ser)
        msg = client.recv(1024).decode('utf-8')
        print(msg)
    非阻塞客户端
    使用的场景
    1. 如果处理的连接数不是很高的话,使用select/epoll的web server不一定比使用multi-threading + blocking
    IO的web server性能更好,可能延迟还更大。select/epoll的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。
    
    2. 在多路复用模型中,对于每一个socket,一般都设置成为non-blocking,但是,如上图所示,
    整个用户的process其实是一直被block的。只不过process是被select这个函数block,而不是被socket IO给block。
    选择的场景
    
    

    I/O 多路复用

    1.3select的基本用法

    # import select
    #
    # fd_r_list, fd_w_list, fd_e_list = select.select(rlist, wlist, xlist, [timeout])
    #
    # 参数: 可接受四个参数(前三个必须)
    #     rlist: wait until ready for reading  #等待读的对象,你需要监听的需要获取数据的对象列表
    #     wlist: wait until ready for writing  #等待写的对象,你需要写一些内容的时候,input等等,也就是说我会循环他看看是否有需要发送的消息,如果有我取出这个对象的消息并发送出去,一般用不到,这里我们也给一个[]。
    #     xlist: wait for an “exceptional condition”  #等待异常的对象,一些额外的情况,一般用不到,但是必须传,那么我们就给他一个[]。
    #     timeout: 超时时间
    #     当超时时间 = n(正整数)时,那么如果监听的句柄均无任何变化,则select会阻塞n秒,之后返回三个空列表,如果监听的句柄有变化,则直接执行。
    # 返回值:三个列表与上面的三个参数列表是对应的
    #   select方法用来监视文件描述符(当文件描述符条件不满足时,select会阻塞),当某个文件描述符状态改变后,会返回三个列表
    #     1、当参数1 序列中的fd满足“可读”条件时,则获取发生变化的fd并添加到fd_r_list中
    #     2、当参数2 序列中含有fd时,则将该序列中所有的fd添加到 fd_w_list中
    #     3、当参数3 序列中的fd发生错误时,则将该发生错误的fd添加到 fd_e_list中
    #     4、当超时时间为空,则select会一直阻塞,直到监听的句柄发生变化
    #
    # # select/epoll的好处就在于单个process就可以同时处理多个网络连接的IO。
    # # 它的基本原理就是select/epoll这个function会不断的轮询所负责的所有socket,
    # # 当某个socket有数据到达了,就通知用户进程
    select的基本用法

    1.4简单版的多路复用

    1.4.1,服务端

    mport select
    import socket
    server = socket.socket()
    server_ip  = ('127.0.0.1',8080)
    server.bind(server_ip)
    rlist = [server,]#要监听的对象
    server.listen()
    
    while 1:
        print('*****')
        r1,w1,e1 = select.select(rlist,[],[])
        print(r1)
        for sock in r1:
            print(r1)
            if sock == server:
                conn,addr = sock.accept()
                rlist.append(conn)
            else:
                from_client_msg = sock.recv(1024)
                print(from_client_msg.decode('utf-8'))
    服务端
    mport socket
    client = socket.socket()
    client.connect(('127.0.0.1',8080))
    while 1:
        to_ser = input('我想说>>>>>').encode('utf-8')
        client.send(to_ser)
        msg = client.recv(1024).decode('utf-8')
        print(msg)
    客户端



  • 相关阅读:
    自制电脑红外遥控接收器(PC软解码) 转
    .NET Micro Framework介绍
    如何测试移动web?
    自行开发高效精简的二进制序列化库(支持精简框架集) 转
    35个优秀的电子商务网站界面
    .Net Micro Framework中的线程
    《肖申克的救赎》 阅后小记
    分享 MSDN 下载工具(Word/PDF)
    OEA ORM中的分页支持
    OEA 中的多国语言实现
  • 原文地址:https://www.cnblogs.com/vivi0403/p/10067323.html
Copyright © 2011-2022 走看看