简介
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模块介绍的详细内容。更多信息请关注PHP中文网其他相关文章!

每天学习Python两个小时是否足够?这取决于你的目标和学习方法。1)制定清晰的学习计划,2)选择合适的学习资源和方法,3)动手实践和复习巩固,可以在这段时间内逐步掌握Python的基本知识和高级功能。

Python在Web开发中的关键应用包括使用Django和Flask框架、API开发、数据分析与可视化、机器学习与AI、以及性能优化。1.Django和Flask框架:Django适合快速开发复杂应用,Flask适用于小型或高度自定义项目。2.API开发:使用Flask或DjangoRESTFramework构建RESTfulAPI。3.数据分析与可视化:利用Python处理数据并通过Web界面展示。4.机器学习与AI:Python用于构建智能Web应用。5.性能优化:通过异步编程、缓存和代码优

Python在开发效率上优于C ,但C 在执行性能上更高。1.Python的简洁语法和丰富库提高开发效率。2.C 的编译型特性和硬件控制提升执行性能。选择时需根据项目需求权衡开发速度与执行效率。

Python在现实世界中的应用包括数据分析、Web开发、人工智能和自动化。1)在数据分析中,Python使用Pandas和Matplotlib处理和可视化数据。2)Web开发中,Django和Flask框架简化了Web应用的创建。3)人工智能领域,TensorFlow和PyTorch用于构建和训练模型。4)自动化方面,Python脚本可用于复制文件等任务。

Python在数据科学、Web开发和自动化脚本领域广泛应用。1)在数据科学中,Python通过NumPy、Pandas等库简化数据处理和分析。2)在Web开发中,Django和Flask框架使开发者能快速构建应用。3)在自动化脚本中,Python的简洁性和标准库使其成为理想选择。

Python的灵活性体现在多范式支持和动态类型系统,易用性则源于语法简洁和丰富的标准库。1.灵活性:支持面向对象、函数式和过程式编程,动态类型系统提高开发效率。2.易用性:语法接近自然语言,标准库涵盖广泛功能,简化开发过程。

Python因其简洁与强大而备受青睐,适用于从初学者到高级开发者的各种需求。其多功能性体现在:1)易学易用,语法简单;2)丰富的库和框架,如NumPy、Pandas等;3)跨平台支持,可在多种操作系统上运行;4)适合脚本和自动化任务,提升工作效率。

可以,在每天花费两个小时的时间内学会Python。1.制定合理的学习计划,2.选择合适的学习资源,3.通过实践巩固所学知识,这些步骤能帮助你在短时间内掌握Python。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

DVWA
Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

记事本++7.3.1
好用且免费的代码编辑器