Original post: http://www.vimer.cn/2009/10/epoll%E5%B7%A5%E4%BD%9C%E6%A8%A1%E5%BC%8F%E8%AF%A6%E8%A7%A3.html
the difference between the Select/epoll
Select Features: Select when selecting a handle, is to traverse all the handles, that is, when the handle has an event response, select needs to traverse all the handles to get to which handles have event notification, so the efficiency is very low. However, if there are few connections, there is little difference in performance compared to the LT trigger mode for select and Epoll.
To say a few words here, the number of handles that are supported by the Select is limited and supports only 1024, which is restricted by the handle set, and if this limit is exceeded, it is likely to result in an overflow, and it is very difficult to find the problem, TAF has seen this problem, debugging N days, Found that: Of course, you can modify the Linux socket kernel to adjust this parameter.
Epoll features: Epoll for handle event selection is not traversal, is the event response, is the handle on the event to select immediately, do not need to traverse the entire handle chain list, so the efficiency is very high, the kernel will handle with red and black tree saved.
For Epoll There is also the difference between ET and LT, lt indicates a level trigger, et represents an edge trigger, both in terms of performance and code implementation is very different.
The difference between LT and et of Epoll
LT: Horizontal trigger, efficiency will be lower than et trigger, especially in large concurrency, large flow of the case. But LT has a low requirement for code writing and is not prone to problems. The performance of the LT Mode Service is that the kernel keeps you informed as long as there is no data being fetched, so don't worry about the loss of the event.
ET: Edge trigger, very high efficiency, in the case of concurrent, large flow, will be less than LT a lot of epoll system calls, so efficient. However, high programming requirements, the need to carefully handle each request, otherwise prone to loss of events.
Here is a Lezilai to illustrate the difference between Lt and ET (both non-blocking mode, blocking is not said, efficiency is too low):
In LT mode, if the accept call has a return, you can immediately establish the current connection, and then epoll_wait wait for the next notification, just like the select.
But for ET, if the accpet call has a return, in addition to establishing the current connection, it is not immediately epoll_wait to continue looping Accpet until return 1, and ERRNO==EAGAIN,TAF The sample code inside:
if (Ev.events & Epollin)
{
do
{
struct sockaddr_in stsockaddr;
socklen_t isockaddrsize = sizeof (sockaddr_in);
Tc_socket CS;
Cs.setowner (false);
Receive connection
Tc_socket s;
S.init (FD, False, af_inet);
int iretcode = S.accept (cs, (struct sockaddr *) &stsockaddr, isockaddrsize);
if (iRetCode > 0)
{
... Establish connection
}
else
{
//until Eagain occurs accept
if (errno = = Eagain)
{break
;
}
}} while (true);
}
Similarly, recv/send and other functions, all need to Errno==eagain
In essence: Compared with LT, the ET model can improve the parallelism efficiency by reducing the system call.
Epoll's Epoll_ctl_del
If Epollrdhup is detected (Stream socket peer closed connection, or shut down writing half of. (This flag are especially useful for writing simple code to detect peer the When using Edge shutdown triggered.) To know is the other side off; some systems cannot detect, can use Epollin,read to return 0, delete the event, turn off Close (FD), note to delete in the close, otherwise error: Bad file descriptor.