全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

深入理解python中的select模块

简介

Python中的select模块专注于I/O多路复用,提供了select  poll  epoll三个方法(其中后两个在Linux中可用,windows仅支持select),另外也提供了kqueue方法(freeBSD系统)

select方法

进程指定内核监听哪些文件描述符(最多监听1024个fd)的哪些事件,当没有文件描述符事件发生时,进程被阻塞;当一个或者多个文件描述符事件发生时,进程被唤醒。

当我们调用select()时:

  1、上下文切换转换为内核态

  2、将fd从用户空间复制到内核空间

  3、内核遍历所有fd,查看其对应事件是否发生

  4、如果没发生,将进程阻塞,当设备驱动产生中断或者timeout时间后,将进程唤醒,再次进行遍历

  5、返回遍历后的fd

  6、将fd从内核空间复制到用户空间

fd:file descriptor 文件描述符

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
  • xlist: wait for an “exceptional condition”
  • timeout: 超时时间

返回值:三个列表

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会一直阻塞,直到监听的句柄发生变化

   当超时时间 = n(正整数)时,那么如果监听的句柄均无任何变化,则select会阻塞n秒,之后返回三个空列表,如果监听的句柄有变化,则直接执行。

实例:利用select实现一个可并发的服务端

import socket
import select

s = socket.socket()
s.bind(('127.0.0.1',8888))
s.listen(5)
r_list = [s,]
num = 0
while True:
 rl, wl, error = select.select(r_list,[],[],10)
 num+=1
 print('counts is %s'%num)
 print("rl's length is %s"%len(rl))
 for fd in rl:
  if fd == s:
   conn, addr = fd.accept()
   r_list.append(conn)
   msg = conn.recv(200)
   conn.sendall(('first----%s'%conn.fileno()).encode())
  else:
   try:
    msg = fd.recv(200)
    fd.sendall('second'.encode())
   except ConnectionAbortedError:
    r_list.remove(fd)


s.close()
import socket

flag = 1
s = socket.socket()
s.connect(('127.0.0.1',8888))
while flag:
 input_msg = input('input>>>')
 if input_msg == '0':
  break
 s.sendall(input_msg.encode())
 msg = s.recv(1024)
 print(msg.decode())

s.close()

在服务端我们可以看到,我们需要不停的调用select, 这就意味着:

  1  当文件描述符过多时,文件描述符在用户空间与内核空间进行copy会很费时

  2  当文件描述符过多时,内核对文件描述符的遍历也很浪费时间

  3  select最大仅仅支持1024个文件描述符

poll与select相差不大,本文不作介绍

epoll方法:

epoll很好的改进了select:

  1、epoll的解决方案在epoll_ctl函数中。每次注册新的事件到epoll句柄中时,会把所有的fd拷贝进内核,而不是在epoll_wait的时候重复拷贝。epoll保证了每个fd在整个过程中只会拷贝一次。

  2、epoll会在epoll_ctl时把指定的fd遍历一遍(这一遍必不可少)并为每个fd指定一个回调函数,当设备就绪,唤醒等待队列上的等待者时,就会调用这个回调函数,而这个回调函数会把就绪的fd加入一个就绪链表。epoll_wait的工作实际上就是在这个就绪链表中查看有没有就绪的fd

  3、epoll对文件描述符没有额外限制

select.epoll(sizehint=-1, flags=0) 创建epoll对象


epoll.close()
Close the control file descriptor of the epoll object.关闭epoll对象的文件描述符

epoll.closed
True if the epoll object is closed.检测epoll对象是否关闭

epoll.fileno()
Return the file descriptor number of the control fd.返回epoll对象的文件描述符

epoll.fromfd(fd)
Create an epoll object from a given file descriptor.根据指定的fd创建epoll对象

epoll.register(fd[, eventmask])
Register a fd descriptor with the epoll object.向epoll对象中注册fd和对应的事件

epoll.modify(fd, eventmask)
Modify a registered file descriptor.修改fd的事件

epoll.unregister(fd)
Remove a registered file descriptor from the epoll object.取消注册

epoll.poll(timeout=-1, maxevents=-1)
Wait for events. timeout in seconds (float)阻塞,直到注册的fd事件发生,会返回一个dict,格式为:{(fd1,event1),(fd2,event2),……(fdn,eventn)}

事件:

EPOLLIN Available for read 可读 状态符为1
EPOLLOUT Available for write 可写 状态符为4
EPOLLPRI Urgent data for read
EPOLLERR Error condition happened on the assoc. fd 发生错误 状态符为8
EPOLLHUP Hang up happened on the assoc. fd 挂起状态
EPOLLET Set Edge Trigger behavior, the default is Level Trigger behavior 默认为水平触发,设置该事件后则边缘触发
EPOLLONESHOT Set one-shot behavior. After one event is pulled out, the fd is internally disabled
EPOLLRDNORM Equivalent to EPOLLIN
EPOLLRDBAND Priority data band can be read.
EPOLLWRNORM Equivalent to EPOLLOUT
EPOLLWRBAND Priority data may be written.
EPOLLMSG Ignored.

水平触发和边缘触发:

Level_triggered(水平触发,有时也称条件触发):当被监控的文件描述符上有可读写事件发生时,epoll.poll()会通知处理程序去读写。如果这次没有把数据一次性全部读写完(如读写缓冲区太小),那么下次调用 epoll.poll()时,它还会通知你在上没读写完的文件描述符上继续读写,当然如果你一直不去读写,它会一直通知你!!!如果系统中有大量你不需要读写的就绪文件描述符,而它们每次都会返回,这样会大大降低处理程序检索自己关心的就绪文件描述符的效率!!! 优点很明显:稳定可靠

Edge_triggered(边缘触发,有时也称状态触发):当被监控的文件描述符上有可读写事件发生时,epoll.poll()会通知处理程序去读写。如果这次没有把数据全部读写完(如读写缓冲区太小),那么下次调用epoll.poll()时,它不会通知你,也就是它只会通知你一次,直到该文件描述符上出现第二次可读写事件才会通知你!!!这种模式比水平触发效率高,系统不会充斥大量你不关心的就绪文件描述符!!!缺点:某些条件下不可靠

epoll实例:

import socket
import select

s = socket.socket()
s.bind(('127.0.0.1',8888))
s.listen(5)
epoll_obj = select.epoll()
epoll_obj.register(s,select.EPOLLIN)
connections = {}
while True:
 events = epoll_obj.poll()
 for fd, event in events:
  print(fd,event)
  if fd == s.fileno():
   conn, addr = s.accept()
   connections[conn.fileno()] = conn
   epoll_obj.register(conn,select.EPOLLIN)
   msg = conn.recv(200)
   conn.sendall('ok'.encode())
  else:
   try:
    fd_obj = connections[fd]
    msg = fd_obj.recv(200)
    fd_obj.sendall('ok'.encode())
   except BrokenPipeError:
    epoll_obj.unregister(fd)
    connections[fd].close()
    del connections[fd]

s.close()
epoll_obj.close()
import socket

flag = 1
s = socket.socket()
s.connect(('127.0.0.1',8888))
while flag:
 input_msg = input('input>>>')
 if input_msg == '0':
  break
 s.sendall(input_msg.encode())
 msg = s.recv(1024)
 print(msg.decode())

s.close()

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。


# python中select怎么用  # python  # select模块  # select与线程  # python爬虫之BeautifulSoup 使用select方法详解  # Python库BeautifulSoup中的select()和select_one()有什么区别  # 遍历  # 句柄  # 回调  # 发生错误  # 上有  # 你不  # 边缘  # 会把  # 太小  # 服务端  # 则将  # 也称  # 下次  # 链表  # 这一  # 就会  # 如果你  # 是在  # 很好  # 在这个 


相关文章: 北京制作网站的公司排名,北京三快科技有限公司是做什么?北京三快科技?  建站主机类型有哪些?如何正确选型  常州企业网站制作公司,全国继续教育网怎么登录?  如何快速打造个性化非模板自助建站?  微信小程序 五星评分(包括半颗星评分)实例代码  如何在VPS电脑上快速搭建网站?  建站之星导航如何优化提升用户体验?  如何在服务器上配置二级域名建站?  实现点击下箭头变上箭头来回切换的两种方法【推荐】  宝华建站服务条款解析:五站合一功能与SEO优化设置指南  实惠建站价格推荐:2025年高性价比自助建站套餐解析  武汉网站如何制作,黄黄高铁武穴北站途经哪些村庄?  香港服务器租用费用高吗?如何避免常见误区?  php条件判断怎么写_ifelse和switchcase的使用区别【对比】  兔展官网 在线制作,怎样制作微信请帖?  电商网站制作价格怎么算,网上拍卖流程以及规则?  建站主机解析:虚拟主机配置与服务器选择指南  定制建站哪家更专业可靠?推荐榜单揭晓  高端建站如何打造兼具美学与转化的品牌官网?  如何在万网自助建站平台快速创建网站?  教学论文网站制作软件有哪些,写论文用什么软件 ?  c# 在ASP.NET Core中管理和取消后台任务  上海制作企业网站有哪些,上海有哪些网站可以让企业免费发布招聘信息?  c# Task.ConfigureAwait(true) 在什么场景下是必须的  如何在Golang中处理模块冲突_解决依赖版本不兼容问题  5种Android数据存储方式汇总  学校免费自助建站系统:智能生成+拖拽设计+多端适配  如何安全更换建站之星模板并保留数据?  南京网站制作费用,南京远驱官方网站?  公司网站的制作公司,企业网站制作基本流程有哪些?  如何在局域网内绑定自建网站域名?  php能控制zigbee模块吗_php通过串口与cc2530 zigbee通信【介绍】  制作门户网站的参考文献在哪,小说网站怎么建立?  大同网页,大同瑞慈医院官网?  可靠的网站设计制作软件,做网站设计需要什么样的电脑配置?  怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?  交易网站制作流程,我想开通一个网站,注册一个交易网址,需要那些手续?  电脑免费海报制作网站推荐,招聘海报哪个网站多?  建站主机CVM配置优化、SEO策略与性能提升指南  如何选择靠谱的建站公司加盟品牌?  如何获取上海专业网站定制建站电话?  建站之星客服服务时间及联系方式如何?  广州商城建站系统开发成本与周期如何控制?  建站主机无法访问?如何排查域名与服务器问题  如何快速生成可下载的建站源码工具?  家庭建站与云服务器建站,如何选择更优?  专业网站制作服务公司,有哪些网站可以免费发布招聘信息?  ,怎么用自己头像做动态表情包?  如何访问已购建站主机并解决登录问题?  建站之星安全性能如何?防护体系能否抵御黑客入侵? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。