这篇文章运用简单易懂的例子给大家介绍python中的选择模块有什么用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
<强>简介强>
python中的选择模块专注于I/O多路复用,提供了select poll epoll三个方法(其中后两个在Linux中可用,windows仅支持选择),另外也提供了kqueue方法(freeBSD系统)
<强>选择方法强>
进程指定内核监听哪些文件描述符(最多监听1024个fd)的哪些事件,当没有文件描述符事件发生时,进程被阻塞;当一个或者多个文件描述符事件发生时,进程被唤醒。
当我们调用select()时:
1,上下文切换转换为内核态
2,将fd从用户空间复制到内核空间
3,内核遍历所有fd,查看其对应事件是否发生
4,如果没发生,将进程阻塞,当设备驱动产生中断或者超时时间后,将进程唤醒,再次进行遍历
5,返回遍历后的fd
6,将fd从内核空间复制到用户空间
fd:文件描述符文件描述符
fd_r_list, fd_w_list fd_e_list=选择。选择(rlist wlist xlist,[超时])
参数:可接受四个参数(前三个必须)
rlist:, wait until ready for 阅读 wlist: wait until  ready for 写作 xlist: wait for  an “exceptional 条件” 超时:超时时间
返回值:三个列表
选择方法用来监视文件描述符(当文件描述符条件不满足时,选择会阻塞),当某个文件描述符状态改变后,会返回三个列表
1,当参数1序列中的fd满足“可读”条件时,则获取发生变化的fd并添加到fd_r_list中
2,当参数2序列中含有fd时,则将该序列中所有的fd添加到fd_w_list中
3,当参数3序列中的fd发生错误时,则将该发生错误的fd添加到fd_e_list中
4,当超时时间为空,则选择会一直阻塞,直到监听的句柄发生变化
当超时时间=n(正整数)时,那么如果监听的句柄均无任何变化,则选择会阻塞n秒,之后返回三个空列表,如果监听的句柄有变化,则直接执行。
<强>实例强>:
利用选择实现一个可并发的服务
import 插座 import 选择 ,, 时间=s socket.socket () s.bind ((& # 39; 127.0.0.1 # 39;, 8888)) s.listen (5) 时间=r_list [s] num =0 while 真正的: ,rl,西城,error =, select.select (r_list, [] [], 10) num +=1 ,打印(& # 39;counts  is % & # 39; % num) ,打印(“rl # 39; s length is % s" % len (rl)) ,for fd  rl拷贝: if 才能;fd ==,年代: ,,,康涅狄格州,addr =, fd.accept () ,,r_list.append(康涅狄格州) ,,msg =, conn.recv (200) ,,conn.sendall((& # 39;第一个- - - - - % & # 39;% conn.fileno ()) .encode ()) 其他的才能: ,,试一试: ,,,msg =, fd.recv (200) ,,,fd.sendall(& # 39;第二# 39;.encode ()) ,,except ConnectionAbortedError: ,,,r_list.remove (fd) ,, s.close ()
import 插座 ,, flag =1 时间=s socket.socket () s.connect ((& # 39; 127.0.0.1 # 39;, 8888)) while 国旗:=,input_msg 输入(& # 39;input>在祝辞& # 39;)==,if input_msg & # 39; 0 & # 39;: ,打破 ,s.sendall (input_msg.encode ())=,,msg  s.recv (1024) ,打印(msg.decode ()) ,, s.close ()
<强> epoll方法:强>
epoll很好的改进了选择:
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,旗帜=0),创建epoll对象 epoll.close () Close 从而,control file descriptor  of 从而epoll 对象。关闭epoll对象的文件描述符 epoll.closed True if 从而epoll object  is 关闭。检测epoll对象是否关闭 epoll.fileno () Return 从而,file descriptor number  of 从而control fd。返回epoll对象的文件描述符 epoll.fromfd (fd) Create an  epoll object 得到a given file 描述符。根据指定的fd创建epoll对象 epoll.register (fd, eventmask]) Register a  fd descriptor  with 从而epoll 对象。向epoll对象中注册fd和对应的事件 epoll.modify (fd, eventmask) Modify a  registered file 描述符。修改fd的事件 epoll.unregister (fd) Remove a  registered file  descriptor 得到,epoll 对象。取消注册 epoll.poll(超时=1,maxevents=1) Wait for 事件只timeout seconds 拷贝(浮动)阻塞,直到注册的fd事件发生,会返回一个dict,格式为:{(fd1 event1), (event2) fd2……(fdn eventn)}python中的选择模块有什么用