[Linux]_02_epoll
1、epoll
epoll是linux大规模并发网络程序中的热门首选模型
1.1 突破一个进程可以打开的socket描述符上限
1.1.1 问题描述
//当前计算机所能打开的最大文件个数,受硬件影响
cat /proc/sys/fs/file-max
//当前用户下的进程,默认打开的文件描述符个数,默认1024
ulimit -a
1.1.2 解决
vi /etc/security/limits.conf
//设置默认值
* soft nofile 65536
//设置上限
* hard nofile 30000
1.2 epoll相关函数
1.2.1 epoll_create
1.2.1.1 函数原型
#include <sys/epoll.h>
int epoll_create(int size);
1.2.1.2 参数
size:创建的红黑树的监听节点数量(仅供内核参考)
1.2.1.3 返回值
- 失败:-1,errno
- 成功:指向新创建的红黑树的根节点的fd
1.2.2 epoll_ctl
1.2.2.1 函数原型
#include <sys/epoll.h>
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
1.2.2.2 参数
- epfd:传入参数,epoll_create函数的返回值,
- op:对该监听红黑树所作的操作
- EPOLL_CTL_ADD //添加fd到监听红黑树
- EPOLL_CTL_MOD //修改fd在监听红黑树上的监听事件
- EPOLL_CTL_DEL //(删除)将fd从监听红黑树上摘下,取消监听
- fd: 带监听的fd
- event: 本质 struct epoll_event 结构体地址
typedef union epoll_data { //联合体
void *ptr; //
int fd; //对应监听事件的fd,对应函数传参的fd
uint32_t u32;
uint64_t u64;
} epoll_data_t;
struct epoll_event {
uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
1.2.3 epoll_wait
1.2.3.1 函数原型
#include <sys/epoll.h>
int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);
1.2.3.2 参数
- epfd:epoll_create 函数的返回值,epfd
- events:用来存放内核事件的集合
- 传出参数
- 传出满足监听条件的那些fd结构体数组
- maxevents:数组,元素的总个数
- timeout:超时时间
- -1:阻塞
- 0:不阻塞
-
0:超时时间
1.2.3.3 返回值
-
0:满足监听的总个数,可以用作循环上限
1.3 fcntl设置非阻塞
//修改connfd为非阻塞
int flag = fcntl(connfd,F_GETFL);
flag |= O_NONBLOCK;
fcntl(connfd,F_SETFL,flag);
1.4 epoll事件模型
1.4.1 ET模式
- 边沿触发
缓冲区剩余未读尽的数据不会导致epoll_wait返回
新的事件满足,才会触发。
struct epoll_event event;
event.events = EPOLLIN|EPOLLET;
1.4.2 LT模式(默认采用模式)
- 水平触发
缓冲区剩余未读尽的数据会导致epoll_wait返回
1.4.3 结论
epoll的ET模式,高效模式,但是只支持 非阻塞模式----忙轮询
1.5 epoll优缺点
- 优点:
高效,可以突破1024文件描述符 - 缺点:
不能跨平台,Linux