---
title: 使用epoll代替select
description: "epoll机制是Linux内核中的一种可扩展I/O事件处理机制，可被用于代替POSIX select系统调用，在高并发场景下获得较好的性能提升。"
url: https://www.hikunpeng.com/document/detail/zh/perftuning/tuningtip/kunpengtuning_12_0029.html
sourcePath: /source/zh/perftuning/tuningtip/kunpengtuning_12_0029.html
indexId: c0a401a654e34ae38a11677265e4ca34b60ae223c0007d98abacfb9177504f8f58
---
# 使用epoll代替select

#### 原理

epoll机制是Linux内核中的一种可扩展I/O事件处理机制，可被用于代替POSIX select系统调用，在高并发场景下获得较好的性能提升。

select有如下缺点：

- 内核默认最多支持1024个文件句柄
- select采用轮询的方式扫描文件句柄，性能差

epoll改进后的机制：

- 没有最大并发连接的限制，能打开的文件句柄上限远大于1024，方便在一个线程中处理更多请求
- 采用事件通知的方式，减少了轮询的开销


#### 修改方式

使用epoll函数代替select，epoll相关函数包括：epoll_create，epoll_ctl和epoll_wait。Linux-2.6.19又引入了支持屏蔽指定信号的epoll_wait: epoll_pwait。

函数简介：

1. 创建一个epoll句柄。
  1 int epoll_create(int size);

  其中size表示监测的文件句柄的最大个数。

2. 注册要监测的事件类型。
```
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
```

参数说明如下：

  - epfd：epoll_create返回的文件句柄。
  - op：要进行的操作，有EPOLL_CTL_ADD、EPOLL_CTL_MOD 、EPOLL_CTL_DEL等。
  - fd：要操作的文件句柄。
  - event：事件描述，常用的事件有：

    - EPOLLIN：文件描述符上有可读数据。
    - EPOLLOUT：文件描述符上可以写数据。
    - EPOLLERR： 表示对应的文件描述符发生错误。
3. 等待事件的产生。
```
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
int epoll_pwait(int epfd, struct epoll_event *events,
int maxevents, int timeout,
const sigset_t *sigmask);
```

参数说明如下：

  - epfd：epoll_create返回的文件句柄。
  - events：返回待处理事件的数组。
  - maxevents：events数组长度。
  - timeout：超时时间，单位为毫秒。
  - sigmask：屏蔽的信号。

在网络高并发场景下，select调用可使用epoll进行替换。

使用如下命令确认是否调用epoll函数：

查看某个进程的系统调用信息

```
strace -p $TID -T -tt
18:25:47.902439 epoll_pwait(716, [{EPOLLIN, {u32=1052576880, u64=281463144385648}}, {EPOLLIN, {u32=1052693569, u64=281463144502337}}, {EPOLLOUT, {u32=1052638657, u64=281463144447425}}, {EPOLLIN|EPOLLOUT|EPOLLRDHUP, {u32=1052673241, u64=281463144482009}}, {EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP|EPOLLRDHUP, {u32=1052636016, u64=281463144444784}}], 512, 1, NULL, 8) = 5 <0.000038>
```
