Epoll is the last extensible I/O event notification mechanism for Linux. There are two main modes of operation
level triggered (LT) is triggered horizontally by default, that is, when a descriptor event is detected and notified to the application by the epoll_wait, the application can not handle the event immediately. The next time you call Epoll_wait, the application will be answered again and notified of this event.
Edge triggered (ET) edges trigger , which means that when the epoll_wait detects a descriptor event and notifies the application of the event, the application must immediately handle the event. If not processed, the next time you call Epoll_wait, the application will not be responded to and notified of this event.
Note: The ET mode greatly reduces the number of times the Epoll event is repeatedly triggered, so the efficiency is higher than the LT mode. Epoll when working in ET mode, you must use a Non-blocking socket interface to avoid starvation of the task of handling multiple file descriptors due to blocking read/blocking write operations on a file handle.
Then corresponding to the socket programming in the accept, read, write, it is necessary to say in detail.
In LT mode, Accept,read,write and normal programming methods do not have to pay special attention to, because as long as the corresponding file descriptor and the data is not read or in a writable state, there will be notification. For example, the Epoll also notifies this event once the data for the buffer is not read at once in the read. can be used on blocking and non-blocking sockets .
However, in et mode, epoll only occurs when the event occurs, and no new events occur without notice. For example, the Epoll does not notify this event again if the data for the buffer is not read all at once in the read. Unless a new event occurs, the listener's descriptor cannot be triggered. can only be used on non-blocking sockets .
Edge triggered event distribution delivers events only if events happens on the monitored file.
Problems existing in accept in ET mode
Consider this scenario: When multiple connections arrive at the same time, the TCP ready queue for the server accumulates multiple ready connections instantaneously, and because of the edge-triggering mode, Epoll only notifies once that the accept handles only one connection, causing the remaining connections in the TCP ready queue to be processed.
The solution is to hold the accept call with a while loop, finish all connections in the TCP ready queue, and then exit the loop. How do I know if I've finished processing all the connections in the ready queue? Accept returns-1 and errno set to Eagain means that all connections are processed.
while ((Conn_sock = Accept (LISTENFD, (struct sockaddr *) &remote, (size_t *) &addrlen)) > 0) {
handle_client (Conn_sock);
}
if (Conn_sock = = 1) {
if (errno!= eagain && errno!= econnaborted && errno!= eproto && Errn o!= eintr)
perror ("accept");
}
In et mode, read the data of the buffer at a time. If read returns 0, then all data is accepted if errno=eagain, indicating that there is still data not received, wait for next notification if read returns-1, indicates an error occurred, stop processing
Receiving an event from epoll_wait (2) should suggest to this such file descriptor is ready for the requested I/O Opera tion. You are have simply to consider it ready until you receive the next Eagain. When and how you'll use such file descriptor are entirely up to you. Also, the condition that the read/write I/O is exhausted can are detected by checking the amount of data read/write F Rom/to the target file descriptor. For example, if your call read (2) is asking to read a certain amount of data and read (2) returns a lower number of bytes, y ou can is sure to have exhausted the read I/O space for such file descriptor. The Same is valid when writing using the Write (2) function.
The above is an official document explanation, once notified that I/O is ready, no matter when you deal with, you can guarantee that the data from the buffer is read. Writing is the same thing.