• 第二十二篇、IO多路复用 一


    一、简介io多路复用

    可以监听多个文件描述符(socket对象)(文件句柄),一旦文件句柄出现变化,就会感知到

    Linux中的 select,poll,epoll(内核2.6以上) 都是IO多路复用的机制

    windows 只支持select

    select性能比较低,并且对文件描述符个数有限制,最多监控1024个

    之后就有了poll,poll相当于对select的优化,对于文件描述符的个数已经没有了限制,但是底层循环都是for循环(被动)

    epoll革新了io多路复用,底层不是用for循环,而是用的异步,要每个句柄谁发发生了变化就告诉epoll,内部实现机制(主动)

    nginx就是socket+epoll来实现的

    注意:网络操作、文件操作、终端操作等均属于IO操作,对于windows只支持Socket操作,其他系统支持其他IO操作,但是无法检测 普通文件操作 自动上次读取是否已经变化。

    Windows Python:

        提供: select
    Mac Python:
        提供: select
    Linux Python:
        提供: select、poll、epoll

    二、首先问一个问题,如何让socketserver端实现监听多个端口?

    监听一个端口代码:

    import socket
    sk = socket.socket()
    sk.bind(("127.0.0.1",993))
    sk.listen()
    while True:
        conn,addre = sk.accept()
        while True:
            conn_bytys = conn.recv(1024)
            conn_str = str(conn_bytys,encoding="utf-8")
            conn.sendall(bytes(conn_str + "",encoding="utf-8"))
        conn.close()

    监听多个端口的server端:

     1 import socket
     2 sk = socket.socket()
     3 sk.bind(("127.0.0.1",993))
     4 sk.listen()
     5 
     6 sk1 = socket.socket()
     7 sk1.bind(("127.0.0.1",991))
     8 sk1.listen()
     9 
    10 sk2 = socket.socket()
    11 sk2.bind(("127.0.0.1",992))
    12 sk2.listen()
    13 
    14 impute = [sk,sk1,sk2,]
    15 import select
    16 while True:
    17     #[sk,sk1,]select内部自动监听 sk1,sk,sk2对象,一旦某个句柄发生变化,就会执行for循环
    18     #最后的1,表示最大等待时间数
    19     #r_list表示impute列表
    20     #里面参数,第一个是监听内部变化,把变化的交给r_list,第三个参数是监听发生错误,如果发生错误,就会去第一个参数里面查找谁出错了,然后摘走放到e_list里面,第二个参数只要有值就会传递个w_list
    21     #上面的就是select的作用io多路复用之一
    22     r_list,w_list,e_list = select.select(impute,[],[],1)
    23     for s in r_list:
    24         #每一个连接对象
    25         conn,addre = s.accept()
    26         conn.sendall(bytes("hello",encoding="utf-8"))
    27         conn.close()
    28     # 下面这个就是第三个参数的应用,即使出错程序也可以继续执行
    29     for s in e_list:
    30         impute.remove(sk)

    上面代码总结:

    #1、[sk,sk1,]select内部自动监听 sk1,sk,sk2对象,一旦某个句柄发生变化,就会执行for循环
    2、最后的1,表示最大等待时间数
    3、r_list表示impute列表
    4、里面参数,第一个是监听内部变化,把变化的交给r_list
    5、第三个参数是监听发生错误,如果发生错误,就会去第一个参数里面查找谁出错了,然后摘走放到e_list里面
    6、第二个参数只要有值就会传递个w_list
    上面的就是select的作用io多路复用之一

    三、select方法:

     1 句柄列表11, 句柄列表22, 句柄列表33 = select.select(句柄序列1, 句柄序列2, 句柄序列3, 超时时间)
     2  
     3 参数: 可接受四个参数(前三个必须)
     4 返回值:三个列表
     5  
     6 select方法用来监视文件句柄,如果句柄发生变化,则获取该句柄。
     7 1、当 参数1 序列中的句柄发生可读时(accetp和read),则获取发生变化的句柄并添加到 返回值1 序列中
     8 2、当 参数2 序列中含有句柄时,则将该序列中所有的句柄添加到 返回值2 序列中
     9 3、当 参数3 序列中的句柄发生错误时,则将该发生错误的句柄添加到 返回值3 序列中
    10 4、当 超时时间 未设置,则select会一直阻塞,直到监听的句柄发生变化
    11    当 超时时间 = 1时,那么如果监听的句柄均无任何变化,则select会阻塞 1 秒,之后返回三个空列表,如果监听的句柄有变化,则直接执行。
    View Code
  • 相关阅读:
    深入了解抽象类和接口
    关于Hibernate查询对象调用set方法自动同步到数据库解决方案
    【鸽子的迷信(一)】python导入由excel文件改后缀变成的csv文件出现乱码错误(ParserError:Error tokenizing data. C error:)
    《计算机操作系统》CH1操作系统引论思维导图整理
    IntelliJ IDEA创建一个Maven项目
    C++实验三
    小练习
    C++实验二
    C++的ch1&ch2的整理
    C++实验一
  • 原文地址:https://www.cnblogs.com/pyrene/p/6430577.html
Copyright © 2020-2023  润新知