epoll函数

socket描述符
在1GB内存的机器上大约是10万左右,具体数目可以cat /proc/sys/fs/file-max查看,一般来说这个数目和系统内存关系很大

epoll_create

int epoll_create(int size);

创建一个epoll的句柄。size为epoll所支持的最大句柄数

epoll_wait

int epoll_wait(int epfd, struct epoll_event *events,
                      int maxevents, int timeout);

events:储存所有的读写事件
maxevents:最大事件数量

epoll_ctl

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *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 events */
    epoll_data_t data;        /* User data variable */
};

epoll_ctl用来添加/修改/删除需要侦听的文件描述符及其事件。任何被侦听的文件符只要被关闭,那么它也会自动从被侦听的文件描述符集合中删除;要尽量少地调用epoll_ctl,防止其引来的开销
EPOLL_CTL_ADD:添加
EPOLL_CTL_MOD:修改
EPOLL_CTL_DEL:删除

举例

int epfd = epoll_create(10);
if(epfd < 0)
{
    perror("epoll_create");
    return epfd;
}

struct epoll_event ev = {0};
struct epoll_event events[10] = {0};

ev.data.fd = sockfd;
ev.events = EPOLLIN|EPOLLET;

int ret = epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);
if(ret < 0)
{
    perror("epoll_ctl");
    return ret;
}

for(;;)
{
    int epfds = epoll_wait(epfd, events, 10, 500);
    if(epfds < 0)
    {
        perror("epoll_wait");
        return epfds;
    }

    int i = 0;
    for(i = 0; i < epfds; i++)
    {
        if(events[i].data.fd == sockfd)
        {
            struct sockaddr_in ss;
            socklen_t len = sizeof ss;
            int afd = accept(sockfd, (struct sockaddr*)&ss, &len);
            if(afd < 0)
            {
                perror("accept");
                return afd;
            }

            printf("接受到新连接 %d
", afd);

            ev.data.fd = afd;
            ev.events = EPOLLIN|EPOLLET;

            int ret = epoll_ctl(epfd, EPOLL_CTL_ADD, afd, &ev);
            if(ret < 0)
            {
                perror("epoll_ctl");
                return ret;
            }
        }
        else if(events[i].events & EPOLLIN)
        {
            char buf[100] = {0};
            memset(buf, 0, sizeof(buf));
            int r = recv(events[i].data.fd, buf, sizeof(buf), 0);
            if(r > 0)
            {
                printf("接收到数据 [%d]: %s
", events[i].data.fd, buf);
            }
        }
    }
}

实验现象

# ./a.out 
接受到新连接 5
接收到数据 [5]: hello 
原文地址:https://www.cnblogs.com/zhangxuechao/p/11709442.html