IO多路复用

IO多路复用 -利用内置模块select[Windows Linux]

  • 循环每一个被监听的项目,看看是否有读写错误操作
  • 所以随着监听项目的增多,效率将变差
  • 服务器端
  • select必须传入三个参数分别是三个列表read_list, write_list, erro_list返回值是一个元祖对应传入的参数

      #select帮助感知某个IO操作是否有变动
      #read开始被read
      #write开始被write
      #erro开始有erro
      #一但感知到就会返回响应的参数
    
    
      import socket
      from select import select
    
      sk = socket.socket()
      address = ('127.0.0.1', 8080)
      sk.bind(address)
      sk.setblocking(False)
      sk.listen() #监听
    
      read_ls = [sk]  #将sk对象加入一个列表
    
      while 1:
          r_ls, w_ls, x_ls = select(read_ls, [], [])
          for i in r_ls:
              if i is sk:
                  conn, addr = i.accept()
                  read_ls.append(conn)
              else:
                  ret = i.recv(1024)  #接收消息
                  if ret == b'':
                      read_ls.remove(i)
                      i.close()
                      continue
                  print(ret)
                  i.send(b'byebye!')  #发送消息
  • 客户端 -起多线程的客户端

      import socket
      from threading import Thread
    
      def func():
          sk = socket.socket()
          address = ('127.0.0.1', 8080)
          sk.connect(address)
          sk.send(b'hello')
          ret = sk.recv(1024)
          print(ret)
          sk.close()
    
      t_ls = []
      for i in range(10):
          t = Thread(target=func)
          t.start()    

其他类似的模块

poll -[Linux]

  • select机制基本上一样
  • 但是poll监听的对象比select监听上限多

epol -[Linux][Windows上没有 ]

  • 高端的
  • 并不是循环每一个项目进行监听
  • 而是为每一个项目增加回调函数
  • 有信号来直接进行回调函数,所以效率比循环高
### IO多路复用的概念 IO多路复用是一种同步I/O模型,允许一个线程同时监控多个文件描述符(如套接字)。这种技术使得程序可以在等待多个输入源中的任何一个变为可用时不会被阻塞。当任意一个文件描述符准备好了读取或写入操作,则会立即通知应用程序去处理相应的工作[^1]。 ### 实现原理 在Linux系统下,可以通过`select`, `poll` 或者更高效的`epoll` 来实现这一功能。这些函数可以让进程一次性监视多个文件描述符,并告知哪些已经准备好进行通信活动。具体来说: - **Select**: 可以监听一定数量的文件描述符集合,在指定时间内检查它们是否有待处理的数据。 - **Poll**: 类似于`select`但是没有最大文件数目的限制,并且性能更好一些因为不需要每次调用都重新构建文件列表。 - **Epoll**: 是一种更为先进的接口,特别适合大量并发连接的情况。它可以注册感兴趣的事件并只报告那些确实发生了变化的对象,从而减少了不必要的上下文切换和资源消耗[^4]。 对于每一个可能发生变化的状态——比如可读、可写或是异常情况发生——都可以设置回调函数以便及时响应。这种方式不仅提高了效率而且简化了编程逻辑。 ### 应用场景 在网络服务端开发领域广泛应用着IO多路复用的技术,尤其是在高负载情况下需要保持大量的活跃TCP连接时表现尤为突出。例如Web服务器(Nginx), 缓存数据库(Redis) 都采用了类似的架构来优化其性能[^5]。 #### Nginx 和 Redis 的例子 这两个软件均采用Reactor模式下的IO多路复用来支持大规模并发请求: - 对于Nginx而言, 主要负责接收新到来的HTTP请求(`accept`)而具体的业务逻辑则由工作进程中完成. - 而像Redis这样的键值存储系统则是完全依赖单个工作循环就能高效地应对成千上万的同时在线客户端. ```python import select import socket server_socket = socket.socket() server_socket.bind(('localhost', 8080)) server_socket.listen(5) inputs = [server_socket] while True: readable, writable, exceptional = select.select(inputs,[],[]) for s in readable: if s is server_socket: client_socket, addr = s.accept() inputs.append(client_socket) else: data = s.recv(1024) if not data: inputs.remove(s) s.close() else: print(f"Received {data.decode()}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值