IO 多路复用

多路复用也是要用单线程来处理客户端并发,与其他模型相比多出了select这个模块。 程序不再直接问操作系统要数据,而是先发起一个select调用,select会阻塞直到其中某个socket准备就绪,此时应用程序再发起系统调用来获取数据,由于select已经帮我们确认了某个socket一定是就绪态,所以后续的recv,send,等操作可以立即完成,不会阻塞。简单的说,select相当于一个中间者,专门帮你看着socket,那个socket准备好了select就返回那个。
你可以把select当做托儿所,把你的socket交给它来看管,当某个socket 要上厕所或者要吃饭的时候,select就会把它交给你。

io多路复用

用一个线程来并发处理所有的客户端

原来我们是直接问操作系统要数据

  如果是io操作 没有数据就会进入阻塞状态

  非io操作 没有数据就会抛出异常,然后继续询问操作系统

在多路复用模型中 要先问select模块 哪些socket已经准备就绪 然后在处理这些已经就绪的select,既然是已经就绪,那么执行recv,或是send 就不会再阻塞                                                                                                                select模块就只有select一个函数

参数1:r_list需要被select检测是否是可读状态的客户端,把所有的socket放到该列表中,select会负责从中找出读取数据的socket

参数2:w_list需要被select检测是否可写的客户端 把所有的socket,select会负责从中找到可以写入数据的socket

参数3:x_list存储着要被检测异常条件。。。忽略即可

返回一个元组 包含三个列表

readables 已经处于可读状态的socket  即数据已经到达缓冲区

writeables 已经处于可写的状态的socket 即缓冲区没满,可以发送

从可读或可写的列表中拿出所有的socket 依次处理他们即可

服务器:

import socket

import select

s = socket.socket()
s.bind(("127.0.0.1",6666))
s.listen()
#在多路复用中 一旦交给select交给你一个socket一定意味着该socket已经准备就绪 可读或者可写

r_list = []
w_list =[]

#存储需要发送的数据 以及对应的socket 把socket作为key 数据作为value
data_dic = {}
while True:
  readables,writeables,_ = select.select(r-_list,w_list,[])

  #接收数据以及服务器建立连接
  for i in readables:
    if i ==s:#如果是服务器 就执行accept
      c,addr = i.accept()
      r_list.append(i)
    else:#是一个客户端 那就recv收数据

      try ;

        data = i.recv(1024)

        #Linux中对方强行下线 或是Windows中正常下线
        if not data:
          i.close()
          r_list.remove(i)
          continue

        print(data)

  #发送数据  不清楚目前是否可以发送数据,所以交给select来检测
        w_list.append(i)

#把要发送的数据先存着,等select告诉你这个连接可以发送时在发送

        data_dic[i]=data

    except ConnectionResetError:#Windows强行下线
        i.close()
        r_list.remove(i)#从检测列表中删除
  for i in writeables:

    try:

      i.send(data_dic[i].upper())#返回数据
      #data_dic.pop(i)
      #w_list.remove(i)

    except ConnectionResetError:#对面下线异常

      i.close()

    finally:

      data_dic.pop[i]
      w_list.remove(i)#从检测列表中删除

      

#客户端

import socket

c = socket.socket()
c.connect((“127.0.0.1”,6666))
print('connect....')
while True:
  msg = input(">>>>").strip()
  if not msg:continue

  c.send(msg.encode.('utf-8')
  data = c.recv(1024)
  print(data.decode.('utf-8')

IO 多路复用的更多相关文章

  1. Python(七)Socket编程、IO多路复用、SocketServer

    本章内容: Socket IO多路复用(select) SocketServer 模块(ThreadingTCPServer源码剖析) Socket socket通常也称作"套接字" ...

  2. IO多路复用概念性

    sellect.poll.epoll三者的区别 先来了解一下什么是进程切换 为了控制进程的执行,内核必须有能力挂起正在CPU上运行的进程,并恢复以前挂起的某个进程的执行,这种行为为进程的切换,任务切换 ...

  3. IO多路复用之select总结

    1.基本概念 IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程.IO多路复用适用如下场合: (1)当客户处理多个描述字时(一般是交互式输入和网络套接口),必须使用I/ ...

  4. IO多路复用之poll总结

    1.基本知识 poll的机制与select类似,与select在本质上没有多大差别,管理多个描述符也是进行轮询,根据描述符的状态进行处理,但是poll没有最大文件描述符数量的限制.poll和selec ...

  5. IO多路复用之epoll总结

    1.基本知识 epoll是在2.6内核中提出的,是之前的select和poll的增强版本.相对于select和poll来说,epoll更加灵活,没有描述符限制.epoll使用一个文件描述符管理多个描述 ...

  6. python中的IO多路复用

    在python的网络编程里,socetserver是个重要的内置模块,其在内部其实就是利用了I/O多路复用.多线程和多进程技术,实现了并发通信.与多进程和多线程相比,I/O多路复用的系统开销小,系统不 ...

  7. socket的IO多路复用

    IO 多路复用 I/O多路复用指:通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作. Linux Linux中的 select,poll, ...

  8. IO多路复用及ThreadingTCPServer源码阅读

    IO多路复用 socket模块是阻塞的,通过socket建立的服务端可以接收多个请求,但只能同时处理一个请求,其他请求都被阻塞.可以通过IO多路复用解决这个问题,socketserver内部使用的就是 ...

  9. 【知乎网】Linux IO 多路复用 是什么意思?

    提问一: Linux IO多路复用有 epoll, poll, select,知道epoll性能比其他几者要好.也在网上查了一下这几者的区别,表示没有弄明白. IO多路复用是什么意思,在实际的应用中是 ...

  10. Python自动化之IO多路复用

    单线程.多线程和异步对比图 灰色的是阻塞 IO多路复用 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方).操作系统的核心 ...

随机推荐

  1. Important persons in deep learning

    Geoffrey Hinton Pieter Abbeel Ian Goodfellow, GAN之父 2019.3 任 Apple Director Andrej Karpathy. 视觉大牛,李飞 ...

  2. luogu P3236 [HNOI2014]画框

    传送门 我们把一种方案的\(\sum a_{i,j}\)和\(\sum b_{i,j}\)看成点\((\sum a_{i,j},\sum b_{i,j})\),那么就只要求横纵坐标之积最小的点,类似于 ...

  3. Linux常用功能及实现命令

    1.设置node.npm.appium等命令全局访问 因为 /opt/node/bin这个目录是不在环境变量中的,所以只能到该目录下才能执行node命令,如果在任意目录下执行node命令的话 ,必须通 ...

  4. python 的基础 学习 12天,函数

    1,   *args   动态 参数,万能参数 *args就是接受实参对应的剩余的位置参数,并将其放在元组中.在定义函数时,*args代表的是聚合. def func(*args): print(ar ...

  5. BigDecimal实现末尾去掉无用0

    BigDecimal 原生提供了 stripTrailingZeros 方法可以实现去掉末尾的 0,然后使用 toPlainString 可以输出数值,注意这里如果使用 toString()  会变成 ...

  6. Python 包

    转载自https://www.cnblogs.com/feeland/p/4401758.html Python 包 包 定义 为了组织好模块,会将多个模块分为包.Python 处理包也是相当方便的. ...

  7. D. Time to go back(思维)

    题目链接:http://codeforces.com/gym/100952/problem/D 题目大意:n个礼物,m个人,要给m个人中的k个人买大于等于d的礼物,其他人随意,问你选择礼物的方案数(不 ...

  8. 识别oracle数据库软件版本号

    由于Oracle数据库不断发展并可能需要维护,因此Oracle会定期生成新版本.并非所有客户最初都订阅新版本或需要对其现有版本进行特定维护.因此,该产品的多个版本同时存在. 可能需要多达五个数字才能完 ...

  9. 困在栅栏里的恺撒WriteUp(附栅栏密码加密解密脚本)

    题目地址:http://www.shiyanbar.com/ctf/1867 这道题目并不难,就是先用栅栏密码解密,然后再用恺撒密码解密就好. 1. 6代表了栅栏密码的栏数(说实话,一开始我也没看出来 ...

  10. Deep Learning Tutorial - Multilayer perceptron

    Multilayer perceptron:多层感知器 本节实现两层网络(一个隐层)作为分类器实现手写数字分类.引入的内容:激活函数(双曲正切.L1和L2正则化).Theano的共享变量.grad.f ...