什么是多路复用IO接口epoll

频繁的I/O操作会引起频繁的系统调用,这会很慢,于是引入缓冲区。对于一个流(文件、socket或pipe),以缓冲区为单位进行操作,举个例子:

一个管道,A写入,B读出,一开始内核缓冲区为空,B阻塞,A开始写入,内核缓冲区状态由空变为非空,这时内核产生一个事件告诉B该醒了。但这个事件并没有让B去读数据,似乎只是起到一个警示,不过内核许诺不会把写入管道中的数据丢掉,A写入的数据会全部保存在缓冲区中,但如果内核缓冲区满了,B还未读数据,这时就会产生I/O事件,告诉进程A不要再写入了,进入阻塞吧。后来B终于开始读数据了,当内核缓冲区空了出来,这时内核就会告诉A,内核缓冲区有空位了,你可以醒了,这也是一个事件。同理,当A不再写入数据,而B将缓冲区读空了,这时内核会让B阻塞。

这个例子是阻塞I/O,在这种模式下,一个线程只能处理一个流的I/O事件,如果要同时处理多个流,需要多进程或多线程,但它们的效率都不高。如果想要用一个线程去处理多个流,只有去轮询多个流,这显然是低效率的。但是如果我们能在轮询之前能判断在这些流中是否产生了I/O事件就好了,这样当得知没有I/O事件,就不去轮询,当得知有I/O事件,再去轮询。这就是select。不过我们从select那里只能知道有I/O事件发生了,却并不知道是那几个流,所以需要轮询全部,还是不够高效。

于是epoll诞生了。epoll会把哪个流发生了怎样的I/O事件通知我们,这样复杂度由O(n)降到O(1),perfect。一个epoll模式的代码大概的样子是:

while true {
    active_stream[] = epoll_wait(epollfd); // 没有I/O事件时阻塞在此,
	                                       // 当有I/O事件时,返回具体的哪个流产生了什么样的事件
    for i in active_stream[] {
        read or write till;
    }
}
时间: 2024-10-14 05:46:01

什么是多路复用IO接口epoll的相关文章

多路复用io接口-epoll

多路复用io接口-epoll的使用. 服务端使用epoll接口处理多个客户的服务请求. 例: 服务端代码 myepoll.c #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #

Linux下多路复用IO接口epoll/select/poll的区别

select比epoll效率差的原因:select是轮询,epoll是触发式的,所以效率高. Select: 1.Socket数量限制:该模式可操作的Socket数由FD_SETSIZE决定,内核默认32*32=1024. 2.操作限制:通过遍历FD_SETSIZE(1024)个Socket来完成调度,不管哪个Socket是活跃的,都遍历一遍. Poll: 1.Socket数量几乎无限制:该模式下的Socket对应的fd列表由一个数组来保存,大小不限(默认4k). 2.操作限制:同Select.

多路复用io接口-select()

io多路转接之系统调用 例: select系统调用的多路转接 #include <stdio.h> #include <stdlib.h> #include <sys/ioctl.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> int main(int argc, char* argv[]) { fd_set rfds; struct timeva

三种多路复用IO实现方式:select,poll,epoll的区别

select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作.但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间. 此时需知道两个概念: 所谓阻塞方式block,顾名思义,就是进程或是线程执行到这些函数时必

linux IO复用(epoll)小记

一.epoll简介 epoll是Linux内核为处理大批量文件描述符而作了改进的poll, 是Linux下多路复用IO接口select/poll的增强版本, 它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率.另一点原因就是获取事件的时候, 它无须遍历整个被侦听的描述符集, 只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了. 二.epoll的API函数 1. 句柄创建函数 int epoll_create(int size); 创建一个epoll的句柄

3高并发服务器:多路IO之epoll

 1 epoll epoll是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并.发连接中只有少量活跃的情况下的系统CPU利用率,因为它会复用文件描述符集合来传递结果而不用迫使开发者每次等待事件之前都必须重新准备要被侦听的文件描述符集合,另一点原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了. 目前epell是linux大规模并发网络程序中的热门首选模型. epoll除了提供s

3高并发server:多路IO之epoll

 1 epoll epoll是Linux下多路复用IO接口select/poll的增强版本号,它能显著提高程序在大量并.发连接中仅仅有少量活跃的情况下的系统CPU利用率,由于它会复用文件描写叙述符集合来传递结果而不用迫使开发人员每次等待事件之前都必须又一次准备要被侦听的文件描写叙述符集合,还有一点原因就是获取事件的时候,它无须遍历整个被侦听的描写叙述符集,仅仅要遍历那些被内核IO事件异步唤醒而增加Ready队列的描写叙述符集合即可了. 眼下epell是linux大规模并发网络程序中的热门首选

五种网络IO模型以及多路复用IO中select/epoll对比

下面都是以网络读数据为例 [2阶段网络IO] 第一阶段:等待数据 wait for data 第二阶段:从内核复制数据到用户 copy data from kernel to user 下面是5种网络IO模型 [阻塞blocking IO] 两阶段全程阻塞 recvfrom -> [syscall -> wait -> copy ->] return OK [非阻塞nonblocking IO] 第一阶段是非阻塞的不断检查是否数据准备好,第二阶段阻塞读取数据 recvfrom -&

多路复用IO

多路复用IO(IO multiplexing) IO multiplexing这个词可能有点陌生,但是如果我说select/epoll,大概就都能明白了.有些地方也称这种IO方式为事件驱动IO (event driven IO).我们都知道,select/epoll的好处就在于单个process就可以同时处理多个网络连接的IO.它的基本原理就是select/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程.它的流程如图: 当用户进