Python多路IO复用之select
前言
这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题
于是乎,我自己开发了一款面试宝典,希望能帮到大家,也希望有更多的Python新人真正加入从事到这个行业里,让python火不只是停留在广告上。
微信小程序搜索:Python面试宝典
或可关注原创个人博客:https://lienze.tech
也可关注微信公众号,不定时发送各类有趣猎奇的技术文章:Python编程学习
Select
- io复用
I/O复用就是单个线程通过记录跟踪每一个Sock(I/O流)的状态来同时管理多个I/O流
目前支持的模型有Select、Poll与Epoll;
select目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点
但是select有一个缺点在于单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024
用Select完成非阻塞方式工作的程序,它能够监视我们需要监视的文件描述符的变化情况,会告诉程序哪些套接字是读、写或是异常状态,我们可以遍历这些套接字的序列,再进行一对一处理
- select模型来自于unix操作系统中,由c而来
int select(int maxfdpl, fd_set * readset, fd_set *writeset, fd_set *exceptset, const struct timeval * tiomeout)
// maxfdpl: 最大的文件描述符长度
// readset: 监听的可读集合
// writeset: 监听的可写集合
// exceptset: 监听的异常集合
// tiomeout: 超时判断
- 在python中对于select模型应用,使用select模块
import select
select.select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)
# rlist: 监听的可读套接字,第一个值往往是服务端套接字
# wlist: 监听的可写套接字
# xlist: 监听的异常套接字
- 使用select复用模型,需要三个循环
循环响应读事件 -> rlist
循环用来处理消息发送 -> wlist
循环处理异常事件 -> xlist
- 参考代码
import select
import socket
import queues = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 服务端套接字
s.setblocking(0) # 非阻塞s.bind(('',8000)) # 绑定可用ip端口
s.listen(5) # 监听套接字in_ = [s] # 待监听的可读队列
'''
s的可读行为: 有新的链接
客户端套接字行为: 有数据发来
'''
out_ = [] # 可写队列,发送消息msg_queue = {}while in_:print('等待下一次事件...')readable, writable, exceptional = select.select(in_, out_, in_)for socket_ in readable: # 监听可读队列if socket_ is s: # 当前套接字为服务端套接字,相应的可读事件为有用户链接来c,c_addr = s.accept()print('有新的套接字连接')c.setblocking(0) # 新连接的客户端套接字设置为非阻塞in_.append(c) # 加入可读监听队列中msg_queue[c] = queue.Queue() # 为当前客户端放置消息存放队列else: # 非服务端套接字,客户端套接字可读事件为有消息发来data = socket_.recv(1024) # 接收客户端数据if data == '': # 客户端断开连接print('套接字关闭...[%s]' % socket_)if socket_ in out_:out_.remove(socket_)in_.remove(socket_) # 在两个监听队列里删除socket_.close()else: # 有客户端消息发来msg_queue[socket_].put(data) # 放置数据到该客户端的消息队列中if socket_ not in out_: # 放置监听套接字到可写事件队列中out_.append(socket_)for socket_ in writable:try:q = msg_queue.get(socket_) # 获取当前是否含有消息队列,待群发消息if q: # 如果存在if q.empty(): # 无消息 踢出队列out_.remove(socket_)else:send_data = q.get_nowait() # 取出消息except:out_.remove(socket_)else:for s_ in in_:if s_ is not s: # 不是服务端套接字try:s_.send(send_data)except:in_.remove(s_)if s_ in out_:out_.remove(s_)s_.close()
Python多路IO复用之select相关推荐
- 多路IO复用模型 select epoll 等
同步阻塞IO在等待数据就绪上花去太多时间,而传统的同步非阻塞IO虽然不会阻塞进程,但是结合轮询来判断数据是否就绪仍然会耗费大量的CPU时间. 多路IO复用提供了对大量文件描述符进行就绪检查的高性能方案 ...
- Redis采用单线程+多路IO复用技术
多路复用指使用一个线程来检查多个文件描述符(Socket)的就绪状态,比如调用select和poll函数,传入多个文件描述符,如果有一个文件描述符就位,则返回,否则阻塞直到超时.得到就绪状态后进行真正 ...
- 多路IO复用(Linux)
一.介绍 多路IO复用,是通过系统底层对描述符事件的检测,通过描述符集合返回,通过描述符集合实现对单一句柄操作 多路IO复用有三种: (1)select (2)poll (3)epoll 对比: 特点 ...
- Redis之单线程+多路IO复用技术
Redis 是单线程+多路IO复用技术 多路复用:使用一个线程来检查多个文件描述符的就绪状态 如果有一个文件描述符就绪,则返回 否则阻塞直到超时 得到就绪状态后进行真正的操作可以在同一个线程里执行,也 ...
- Redis网络多路IO复用以及底层原理
老早听说过Redis是单线程,但指的是什么单线程,为什么单线程,底层实现原理是什么? 单线程指的是Redis中处理网络请求的模块是单线程处理的,并非指整一个Redis软件都是单线程,肯定有其它线程做其 ...
- Redis采用的单线程+多路IO复用
为什么redis是单线程的? 首先并不是高性能服务器都是多线程来实现的,因为reids的核心就是数据在内存中,他单线程的去操作就是效率最高的.单线程可以避免上下文的切换和锁的竞争. 一次CPU上下文切 ...
- 【python】-- IO多路复用(select、poll、epoll)介绍及实现
IO多路复用(select.poll.epoll)介绍及select.epoll的实现 IO多路复用中包括 select.pool.epoll,这些都属于同步,还不属于异步 一.IO多路复用介绍 1. ...
- Linux网络编程(高级IO)-典型IO,多路IO复用
IO:输入输出 过程:等待IO就绪,进行数据拷贝 四种典型IO方式: (1)阻塞IO:发起IO调用,若IO未就绪(IO条件不具备)则一直等待 (2)非阻塞IO:发起IO调用,若IO未就绪(IO条件 ...
- 多路 IO 转接 :select 函数
(1)头文件: #include <sys/select.h> (2)函数原型: int select( int nfds, fd_set *readfds, fd_set *writef ...
最新文章
- gulp前端自动化工具的快速入门案例
- ppt生成器_WPS又有新动作!发布新款PPT快速生成器,职场办公必备
- 【项目管理】不确定性绩效域管理
- 惠普打印信息页无法连接到服务器,惠普M400系列打印机网络连接无法打印怎么办?...
- html5金牌榜,member-Grading.html
- 猜数字游戏的提示(UVa340)
- Fastjson批量检查及一键利用工具
- 汉堡王什么汉堡好吃_汉堡王10元汉堡太好吃了,秒杀肯德基和麦当劳,一次吃两个...
- TCP/IP and Socket
- 【EVE模拟器是干什么的】
- python下载网页中的pdf文件_Python下载PDF嵌入页面
- EndNote导出毕业论文格式的参考文献
- hard link and symbolic link
- Maven报:Unable to import maven project: See logs for details
- 趣味程序设计_出售金鱼
- 基于Curator的Zookeeper操作实战
- JS 实现网站简繁体切换
- ffmpeg转码过程分析
- 审查元素html表格后缀,审查元素
- linux中安装openoffice,及解决转pdf时中文乱码或者中文不显示问题【离线】