Event poll epoll details

Source: Internet
Author: User

Due to the limitations of Poll () and select (), the 2.6 kernel introduces the event poll (epoll) mechanism. Although a little complicated, epoll solves their common basic performance problems and adds some new features.

Each call of Poll () and select () requires all the file descriptors to be listened on. The kernel must traverse all monitored file descriptors. When this table becomes very large, the traversal of each call becomes a significant bottleneck with hundreds of file descriptors.

1. Create a New epoll instance

Use epoll_create () or epoll_cerate1 () to create an epoll context. Here epoll_cerate1 () is an extended version of epoll_cerate.

#include <sys/epoll.h>int epoll_create (int size)

After the call is successful, epoll_create () creates an epoll instance and returns the file descriptor associated with the instance. This file descriptor has nothing to do with the real file. It is only created to call epoll later. The size parameter indicates the number of file descriptors to be monitored by the kernel, but not the maximum value. Passing an appropriate approximate value will improve performance, but no exact number is required. When an error occurs,-1 is returned, and errno is set to one of the following values:

EinvalSize is not a positive number

EnfileThe maximum number of opened files has been reached.

EnomenThere is not enough memory to complete this operation.

The standard call is as follows:

int epfd;epfd = epoll_create (100); if (epfd <0 )perror("epoll_create");

The file descriptor returned by epoll_create must be closed with close.

2. epoll Control

Epoll_ctl can be used to add or delete file descriptors to the specified epoll context:

#include <sys/epoll.h>int epoll_ctl (int epfd, int op, int fd, struct epoll_event *event);
The epoll event struct is defined in the header file <sys/epoll. h>.
 
struct epoll_event {_u32 events;union {void * ptr;int fd;_u32 u32;_u64 u64;}data;};
Epoll_ctl () is associated with the epoll instance and epfd. The OP parameter specifies the operation to be performed on FD. The event parameter describes more specific epoll behaviors.
The following are the valid values of the OP parameter:
Epoll_ctl_addAdd the file specified by FD to the epoll instance listening set specified by epfd to listen for events defined in the event.
Epoll_ctl_delDelete the file specified by FD from the epoll listener set specified by epfd.
Epoll_ctl_modUse event to change the listening behavior on the existing FD.
The event parameter in the epoll_event struct lists the events monitored on the given file descriptor. Multiple events can be specified simultaneously using bitwise OR operations. The following are valid values:
EpollerrFile error. Even if this flag is not set, this event is also monitored.
EpolletEdge trigger. The default value is horizontal triggering.
EpollhupThe file is suspended. Even if this flag is not set, this event is also monitored.
EpollinThe file is not blocked and readable.
EpolloneshotAfter an event is generated and processed, the file is not monitored. It must not be listened on again. You must use epoll_ctl_mod to specify a new event to re-Listen to the file.
EpolloutThe file is not blocked and can be written.
EpollpriHigh-priority out-of-band data is readable.
The data field in event_poll is used by the user. After the listener event is confirmed, data is returned to the user. Generally, the event. Data. FD is set to fd, so that you can know the file descriptor trigger event.
When the call succeeds, epoll_ctl () returns 0. If the call fails,-1 is returned, and errno is set to the following values:
EbadfEpfd is not a valid epoll instance, or FD is not a valid file descriptor.
EexistOP is epoll_ctl_add, but FD is already associated with epfd.
EinvalEpfd is not an epoll instance. epfd is the same as FD, or op is invalid.
EnoentOP is epoll_ctl_mod or epoll_ctl_del, but FD is not associated with epfd.
EnomenThere is not enough memory to complete the process request.
EpermFD does not support epoll.
Add a listener file specified by FD to the epfd instance and use the following code:
struct epoll_event event;int ret;event.data.fd = fd;/*return the fd to us later*/event.events = EPOLLIN|EPOLLOUT  ;ret = epoll_ctl (epfd,EPOLL_CTL_MOD,fd,&event);if (ret)perror ("epoll_ctl");
You can use the following code to modify a listener event on the FD of an epfd instance:
struct epoll_event event;int ret;event.data.fd = fd;/*return the fd to us later*/event.events = EPOLLIN ;ret = epoll_ctl (epfd,EPOLL_CTL_MOD,fd,&event);if (ret)perror ("epoll_ctl");
To delete an FD listening event, use the following code:
struct epoll_event event;int ret;event.data.fd = fd;/*return the fd to us later*/event.events = EPOLLIN ;ret = epoll_ctl (epfd,EPOLL_CTL_DEL,fd,&event);if (ret)perror ("epoll_ctl");
3. Wait for the epoll event
Epoll_wait:
#include <sys/epoll.h>int epoll_wait (int epfd, struct epoll_event * * events, int maxevents, int timeout);
Call epoll_wait () to wait for the event on the file FD in the epfd of the epoll instance. The time limit is timeout milliseconds. If a success is returned, events points to the memory containing the epoll_event struct (which describes each event,
You can have a maximum of maxevents events. The returned value is the number of events, error-1 is returned, and errno is set to the following values
EbadfEpfd is an invalid file descriptor.
EfaultThe process has no write permission on the memory indicated by events.
EintrSystem Call is interrupted by signal before completion
EinvalEpfd is not a valid epoll instance, or maxevents is less than or equal to 0
If the timeout value is 0, the call will occur immediately even if no event occurs. At this time, the call will return 0. If the timeout value is-1, the call will wait until an event occurs.
When epoll_wait () is called to return, the events array in the epoll_event struct describes a waiting event, and a maximum of maxevents events are returned. The data field contains the user's settings before calling epoll_ctl,
For example, the file handle is used to differentiate the events that occur in the file.
An example of a complete epoll_wait () is as follows:
#define MAX_EVENTS   64struct epoll_event * events = NULL;int nr_events, i, epfd;events = malloc (sizeof(struct epoll_event) * MAX_EVENTS);if (! events ){perror("malloc");exit(-1);}nr_events = epoll_wait (epfd,events,MAX_EVENTS,-1);if (nr_events < 0){perror("epoll_wait");free(events);exit (-1);}for (int i=0; i<nr_eventsl i++)printf("event = %d on fd = %d \n",events[i].events,events[i].data.fd);
 
4. Edge trigger time and horizontal trigger event

There are two types of epoll events:Level triggered (LT)AndEdge triggered (ET ):

LT (Level triggered, horizontal trigger mode) is the default mode of work, and supports both block and non-block socket. In this way, the kernel tells you whether a file descriptor is ready, and then you can perform Io operations on this ready FD. If you do not perform any operation, the kernel will continue to inform you, so the possibility of programming errors in this mode is lower.

Et (edge-triggered, edge trigger mode) is a high-speed operation mode that only supports no-block socket. In this mode, when the descriptor is never ready, the kernel tells you through epoll. Then it will assume that you know that the file descriptor is ready and will not send more ready notifications for that file descriptor. The event will not be ready again until new data comes in next time.

5. Instances in man epoll

The setnonblocking () function sets the socket file to non-blocking because the et mode is used. Do_use_fd () is used to process this file, such as reading and writing.

#define MAX_EVENTS 10struct epoll_event ev, events[MAX_EVENTS];int listen_sock, conn_sock, nfds, epollfd;/* Set up listening socket, ‘listen_sock‘ (socket(),    bind(), listen()) */epollfd = epoll_create(10);if (epollfd == -1) {    perror("epoll_create");    exit(EXIT_FAILURE);}ev.events = EPOLLIN;ev.data.fd = listen_sock;if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) {    perror("epoll_ctl: listen_sock");    exit(EXIT_FAILURE);}for (;;) {    nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);    if (nfds == -1) {        perror("epoll_pwait");        exit(EXIT_FAILURE);    }    for (n = 0; n < nfds; ++n) {        if (events[n].data.fd == listen_sock) {            conn_sock = accept(listen_sock,                            (struct sockaddr *) &local, &addrlen);            if (conn_sock == -1) {                perror("accept");                exit(EXIT_FAILURE);            }            setnonblocking(conn_sock);            ev.events = EPOLLIN | EPOLLET;            ev.data.fd = conn_sock;            if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock,                        &ev) == -1) {                perror("epoll_ctl: conn_sock");                exit(EXIT_FAILURE);            }        } else {            do_use_fd(events[n].data.fd);        }    }}

Event poll epoll details

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.