码迷,mamicode.com
首页 > 其他好文 > 详细

I/O Multiplexing

时间:2020-10-24 10:14:46      阅读:21      评论:0      收藏:0      [点我收藏+]

标签:alt   描述   用户态   line   linu   系统调用   multi   sdn   ref   

当多个独立的I/O事件同时发生时,I/O多路复用是一种解决方式。
为了提高服务器的吞吐量,单个线程通过记录跟踪每个I/O流的状态同时管理多个I/O流,非常类似时分复用技术。
技术图片
I/O多路复用的具体实现方式有3种:select()poll()epoll()

select

select()系统调用:int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
select()会一直阻塞直到至少一个文件描述符就绪,可以读写,或者出现异常。
中间3个参数会被修改,表示哪个FD准备好了,最后一个表示等待时间,NULL表示无限等待。
返回就绪的FD数目,有错-1。只知道有就绪,不知道哪个FD就绪了。

int s = socket();
bind();
listen();

int fd[];  // 需要监听的socket集合
while (1) {
	int n = select();
	for (int i = 0; i < fd.size(); ++i) {
		if (FD_ISSET()) {  // 判断哪个socket接收到数据
			// 处理数据
		}
	}
}

select()是阻塞方法,只有某个socket接收到数据才会继续执行,唤醒进程。
直接的方式缺点就比较多:

  • 时间开销大,所以规定最多监听1024个socket;
  • 每次调用都要把fd集合从用户态拷贝到内核态。
  • 线程不安全:

If a file descriptor being monitored by select() is closed in another thread, the result is unspecified.

poll

去掉了1024的限制,线程不安全。

epoll

线程安全,知道哪个FD就绪,只有Linux支持。
相比于select()epoll()不会无差别轮询,只处理接收到数据的socket,这样复杂度就降低为\(O(k)\)

Reference

I/O多路复用是什么意思

I/O Multiplexing

标签:alt   描述   用户态   line   linu   系统调用   multi   sdn   ref   

原文地址:https://www.cnblogs.com/EIMadrigal/p/13558310.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!