class="markdown_views prism-atom-one-light">
在linux中,多路IO复用的方式有select poll epoll这几种方式。selece和poll,都不是线程安全的,而epoll是线程安全的。epoll在大并发的情况下,性能远高于selece和poll机制。
epoll C API
- int epoll_create(int size);
- 功能:创建epoll
- 参数:
- size: 从内核2.6开始,size的值已经被忽略,但是这个值必须要大于0
- 返回值: 成功返回文件描述符,失败返回 -1, errno中含有失败的原因
- int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
- 功能:用于添加或者移除对目标fd的监控
- 参数:
- epfd:epoll_create返回的文件描述符
- op:
– EPOLL_CTL_ADD 和fd相关文件的添加
– EPOLL_CTL_MOD 和fd相关文件的修改
– EPOLL_CTL_DEL 和fd相关文件的移除
- fd:目标文件描述符
- event:event是和fd相关的描述 epoll_event的结构体如下
typedef union epoll_data {
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
struct epoll_event {
uint32_t events;
epoll_data_t data;
};
events的可选项
EPOLLIN EPOLLOUT EPOLLRDHUP等
- int epoll_wait(int epfd, struct epoll_event *events,
int maxevents, int timeout);
- 功能:等待epoll事件的发生,发生的事件保存在events中
- 参数
- events:存放这发生的事件
- maxevents 最大的发生时间数
- timeout epoll_wait超时时间
- 返回值:发生的事件个数
epoll 实例
在代码中,监控目录下的文件的输入EPOLLIN,当时间发生后,通过fd读取相应的内容
#include
#include
#include
#include
#include
#include
#include
#define DATA_MAX_LEN 500
int add_to_epoll(int fd, int epollFd)
{
int result;
struct epoll_event eventItem;
memset(&eventItem, 0, sizeof(eventItem));
eventItem.events = EPOLLIN;
eventItem.data.fd = fd;
result = epoll_ctl(epollFd, EPOLL_CTL_ADD, fd, &eventItem);
return result;
}
void rm_from_epoll(int fd, int epollFd)
{
epoll_ctl(epollFd, EPOLL_CTL_DEL, fd, NULL);
}
int main(int argc, char **argv)
{
int mEpollFd;
int i;
char buf[DATA_MAX_LEN];
static const int EPOLL_MAX_EVENTS = 16;
struct epoll_event mPendingEventItems[EPOLL_MAX_EVENTS];
if (argc < 2)
{
printf("Usage: %s [file2] [file3] ...
", argv[0]);
return -1;
}
mEpollFd = epoll_create(8);
for (i = 1; i < argc; i++)
{
int tmpFd = open(argv[i], O_RDWR);
add_to_epoll(tmpFd, mEpollFd);
}
while (1)
{
int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, -1);
for (i = 0; i < pollResult; i++)
{
printf("Reason: 0x%x
", mPendingEventItems[i].events);
int len = read(mPendingEventItems[i].data.fd, buf, DATA_MAX_LEN);
buf[len] = '