标签:udp 方案 com io多路复用 style 了解 技术分享 监听 其他
IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程。IO多路复用适用如下场合:
当客户处理多个描述符时(一般是交互式输入和网络套接口),必须使用I/O复用。
当一个客户同时处理多个套接口时,而这种情况是可能的,但很少出现。
如果一个TCP服务器既要处理监听套接口,又要处理已连接套接口,一般也要用到I/O复用。
如果一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用。
如果一个服务器要处理多个服务或多个协议,一般要使用I/O复用。
与多进程和多线程技术相比,I/O多路复用技术的最大优势是系统开销小,系统不必创建进程/线程
,也不必维护这些进程/线程,从而大大减小了系统的开销。
目前支持I/O多路复用的系统调用有 select,pselect,poll,epoll
,I/O多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作
。但select,pselect,poll,epoll本质上都是同步I/O
,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。
对于IO多路复用机制不理解的同学,可以先行参考《聊聊Linux 五种IO模型》,来了解Linux五种IO模型。
epoll跟select都能提供多路I/O复用的解决方案。在现在的Linux内核里有都能够支持,其中epoll是Linux所特有,而select则应该是POSIX所规定
,一般操作系统均有实现。
基本原理:
select 函数监视的文件描述符分3类,分别是writefds、readfds、和exceptfds。调用后select函数会阻塞,直到有描述符就绪(有数据 可读、可写、或者有except),或者超时(timeout指定等待时间,如果立即返回设为null即可),函数返回。当select函数返回后,可以通过遍历fdset,来找到就绪的描述符。
基本流程,如图所示:
select目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点
。select的一个缺点在于单个进程能够监视的文件描述符的数量存在最大限制
,在Linux上一般为1024,可以通过修改宏定义甚至重新编译内核的方式提升这一限制
,但是这样也会造成效率的降低。
select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理
。这样所带来的缺点是:
一般来说这个数目和系统内存关系很大,
具体数目可以cat /proc/sys/fs/file-max察看
。32位机默认是1024个。64位机默认是2048.
当套接字比较多的时候,每次select()都要通过遍历FD_SETSIZE个Socket来完成调度,不管哪个Socket是活跃的,都遍历一遍。这会浪费很多CPU时间。
如果能给套接字注册某个回调函数,当他们活跃时,自动完成相关操作,那就避免了轮询
,这正是epoll与kqueue做的。
需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大。
select只能是监听socket对象?
只要里面监听的对象里面有fileno方法,并且可以返回文件描述符就可以放在select里面被监听,只要你放入的对象里面有fileno方法,只要有fileno方法,就能返回文件描述符
class FOO(): def fineno(self): obj=socket() return obj.fileno() 返回对象的fineno方法
什么时候才会有阻塞?
当你请求连接的时候,或者是进行接收到数据(等待服务器响应的时候)的时候都会发生阻塞
select后面监听的是什么?
第一个监听的是建立通信成功的socket对象,第二个监听的是已经创建连接成功的socket对象,第三个发生异常的socket对象,后面是你最多可以延迟的时间
rlist,wlist,elist=select.select(self.conn,self.conection,self.conn,0.05)###
什么是异步io?
异步就是当你进行其他请求的时候,可以进行其他请求的处理,就是说当你遇到哦io操作的时候,也可以处理其他io请求,非阻塞的io加io多路复用
标签:udp 方案 com io多路复用 style 了解 技术分享 监听 其他
原文地址:https://www.cnblogs.com/yunxintryyoubest/p/10035780.html