1.epoll函数为什么优于select函数
select函数的缺点:
- 调用select函数后,要针对所有文件描述符进行循环处理。
- 每次调用select函数,都需要向该函数传递监视对象信息。
对于缺点2,是提高性能的最大障碍。因为,套接字是操作系统来管理的,所以每次调用select函数,都会将要监视的对象信息传递给操作系统,这会对程序造成很大的负担。而且无法通过代码来解决,所以,缺点2是提高性能的最大障碍。
所以,有没有这么一种函数,仅向操作系统传递一次监控对象,当监视范围或内容发生变化时,只通知发生变化的事项呢?
答:epoll函数就具有问题里所说的功能。
适合select函数的使用情形:
- 系统需要具有兼容性。epoll函数是基于Linux系统的,而select函数几乎所有系统都有。
- 服务器端接入者少。
综上,epoll函数的优点:
- 无需编写以监视状态变化为目的的针对所有文件描述符的循环语句
- 调用对应于select函数的epoll_wait函数时,无需每次都传递监视对象信息,造成性能负担。
2.epoll函数
2.1 epoll_create函数
作用:创建保存epoll文件描述符的空间
#include <sys/epoll.h>
int epoll_create(int size); //size:epoll实例的大小
成功返回epoll文件描述符
失败返回-1
调用epoll_create函数时创建的文件描述符保存空间称为“epoll例程”。
size参数的传递,只是向操作系统提供建议,实际上操作系统会根据情况调整epoll例程的大小。更实际上的是,Linux2.6.8版本后的内核将完全忽略size参数。
注意:epoll_create函数创建的资源与套接字相同,都由操作系统来管理。所以返回的epoll文件描述符主要用于区分epoll例程的,需要终止时,也要和其他文件描述符相同,要调用close函数。
2.2 epoll_ctl函数
作用:向空间注册或注销文件描述符
#include<sys/epoll.h>
int epoll_ctl(
int epfd, //用于注册监视对象的epoll例程的文件描述符
int op, //用于指定监视对象的添加、删除、更改操作
int fd, //需要监视的文件描述符
struct epoll_event* event //监视对象的事件类型
);
成功返回0,失败返回-1
参数epfd:指定epoll例程空间
参数op:
值 | 含义 |
EPOLL_CTL_ADD | 将文件描述符注册到epoll例程 |
EPOLL_CTL_DEL | 将文件描述符从epoll例程中删除,第四个参数填NULL |
EPOLL_CTL_MOD | 更改注册的文件描述符的关注事件发生情况 |
参数fd:需要监视的文件描述符
参数event:
struct epoll_event
{
__uint32_t events;
epoll_data_t data;
}
typedef union epoll_data
{
void* ptr;
int fd;
__uint32_t u32;
__uint64_t u64;
}epoll_data_t
events常量(可以通过位或“|”运算符来传递多个参数) | 含义 |
EPOLLIN | 需要读取数据的情 |