Frequent I/O operations can cause frequent system calls, which is slow, so the buffer zone is introduced. For a stream (file, socket, or pipe), operations are performed in buffer units. For example:
One Pipeline, write a, read B, the kernel buffer is empty at first, B is blocked, A is written, and the kernel buffer status is changed from null to non-empty, at this time, the kernel generates an event to tell B to wake up. However, this event does not allow B to read data. It seems to be a warning, but the kernel promises not to discard the data written into the pipeline, and all the data written by a will be saved in the buffer zone, however, if the kernel buffer is full and B has not read the data, an I/O event will be generated, telling process a not to write any more, and blocking will occur. Later, B finally began to read data. When the kernel buffer is empty, then the kernel will tell a that there is space in the kernel buffer and you can wake up. This is also an event. Similarly, when a no longer writes data and B does not read the buffer, the kernel Blocks B.
This example is to block I/O. In this mode, a thread can only process the I/O events of one stream. To process multiple streams at the same time, multiple processes or multithreading are required, however, their efficiency is not high. If you want to use a thread to process multiple streams, you only need to poll multiple streams, which is obviously inefficient. However, if we can determine whether I/O events have been generated in these streams before polling, so that when we know that there is no I/O event, we will not go round-robin, when I/O events are detected, round robin is performed. This is select. However, from the SELECT statement, we can only know that there is an I/O event, but we do not know the several streams. Therefore, it is not efficient to round all the streams.
Epoll was born. Epoll will notify us of the I/O event of the stream, so that the complexity is reduced from O (n) to O (1) and perfect. The code in an epoll mode looks like:
While true {active_stream [] = epoll_wait (epollfd); // when there is no I/O event, it is blocked here. // when there is an I/O event, returns the specific aborted event for I in active_stream [] {read or write till ;}}
What is epoll