Thinking Caused by select, Thinking Caused by select
I. Preface
A classic question in network programming: What is the difference between selec, poll and epoll? This problem was introduced when I first learned programming. At that time, I was not clear about the materials I had read, and I had no idea about many concepts and ideas. Now, at this stage, I will look back at this problem again, there is a sense of openness,
Record what I can understand.
References: https://www.cnblogs.com/zingp/p/6863170.html
Http://blog.csdn.net/a837199685/article/details/45954349
Https://www.zhihu.com/question/32163005
Http://shmilyaw-hotmail-com.iteye.com/blog/1896683
Http://www.cnblogs.com/my_life/articles/3968782.html
Https://www.cnblogs.com/Anker/p/3265058.html
Ii. Starting from the Operating System
There are several concepts that I have been talking about in the future. It is necessary to understand them first. In the past, this step was not done. When I learned it, I was overwhelmed.
1. user space and kernel space
The addressing mode of the operating system is virtual addressing, that is, the processor generates virtual addresses, translates them into physical addresses, and processes the bus to the physical address. The processor obtains the processed data.
The core of the operating system is the kernel, which can access the protected memory space, access the underlying hardware facilities, and do anything. Therefore, the kernel should be protected for system stability.
Therefore, virtual space is divided into kernel space and user space. The kernel space is at most 1 GB, and the user space is in the remaining memory.
Most of the processes we use are processed in the user space, sending requests to the kernel, and operating hardware in the kernel space.
2. process context switching (process switching)
We all know that suspending the current process and resuming a process is a costly process. What are the specific steps?
First, save the necessary information of the current process for future recovery, such as the page table describing the address space, the progress table, and the file table.
Switch to the global directory on the page and install a new address space.
Finally, reply to the context of the target process.
3. file descriptor (fd)
A term in a computer that points to an abstract representation of a file object. It is a non-negative integer index value, pointing to a file in the file table
When a program opens or creates a file, the kernel returns a file descriptor to the process, representing the file.
Through the operation file descriptor, we can achieve the goal of real operation files
4. process block)
When a process waits for an execution result, it blocks itself (not an officer) until the result is obtained and continues,
The key point is: this is the process's own behavior, and does not occupy cpu resources (cpu is not counted) when blocking ),
Therefore, I/O requests have a low performance. As the saying goes, they occupy the pitfalls and do not take a long time. They also exist in computers. Therefore, we have designed multithreading, multi-process, and other solutions to solve this problem.
5. I/O Process
There are generally two modes: Direct I/O, cache I/O (default ),
Cache I/O:
The process initiates a system call (notifying the system that I want to read and write !)
Write: Process (data) ------- process buffer pool ---------- kernel buffer pool ---------- storage device
Read: storage device (data) --------- kernel buffer pool ---------- process buffer pool --------- Process
Direct I/O (the process cache pool disappears !) :
The process initiates a system call (notifying the system that I want to read and write !)
Write: Process (data) ---------- kernel buffer pool ---------- storage device
Read: storage device (data) --------- kernel buffer pool --------- Process
Each of the preceding steps may block the process. Depending on the blocking at different locations, multiple network modes are created to adapt to different scenarios.
Iii. I/O mode (read as an example)
1. block I/O
Process:
The process initiates a system call (notifying the system that I want to read and write !)
Read: storage device (data) --------- kernel buffer pool --------- process ---------- kernel notification process OK, process unblocking
Process blocking process Blocking
Explanation:
The process waits until the file is ready and continues the next step.
Application scenarios:
The above principle is a user connection, which is easy to understand.
When a server is connected to multiple clients:
Preliminary solution: multi-process (big data or long-time tasks, high overhead, more secure) or multi-thread (many connections, low overhead, less secure to put data together) create a connection for each client.
Insufficient: High concurrency reflects high overhead and low performance. One is multi-thread switching, the performance overhead of context switching, and the other is that a large number of threads occupy a large amount of system resources.
Optimization solution: Use a thread pool (reduce the frequency of thread creation and destruction) or a connection pool (maintain a connection cache pool and reuse existing connections as much as possible) to reduce system overhead
Deficiency: there are limits to reduce the overhead. In this era, high concurrency is high and it is easy to reach the bottleneck.
2. non-block I/O
Process:
Initiate a system call (notify the system that I want to read and write !)
Read: storage device (data) ------------- kernel buffer pool ----------- process ----------- kernel notification process OK, process unblocking
Non-blocking
Explanation:
In the data preparation stage of the kernel, an error is immediately returned to the process,
So the process knows that the kernel is not ready yet,
So the process asks the kernel again, and then the kernel returns an error until the kernel is ready. When asked, the system returns the prepared signal, and the process becomes congested,
Application scenarios:
Small connection volume, no difference,
When the number of connections is large, this mode can theoretically implement multiple connections using one thread:
Due to non-blocking, this thread can cyclically ask if all connection targets are ready, and the kernel will immediately reply with an error. If the thread is ready, it will be handed over to the process, so it will not waste time,
However, (everything works), the efficiency of this simple implementation scheme is still very low. After all, from the kernel space to the user space is still block, and it will greatly increase the cpu usage.
Especially when the response event (read or other) is large, the execution speed will be very slow.
The following select statement is based on this idea.
3. I/O multiplexing
Objective: To handle highly concurrent requests with low overhead and High Efficiency
Solutions: select, poll, and epoll
Essence: select, poll, and epoll are used to listen to all socket objects. When the socket object changes, the user process is notified for processing.
Features:
Select (first appearance): supported by multiple platforms
Low efficiency with round robin
The number of connections processed is limited. The default value is 1024,
Copy of a large number of user States and kernel state fd, with low performance,
The returned list of all handles does not tell which one has changed. The user process has to traverse it again.
Poll (slightly improved): improved the number of connections limit, so that the number of connections is not limited.
Epoll (improving all disadvantages): When the socket changes, it notifies the process which has completed,
Unlimited number (maximum number of files opened by the System)
Fd handle is copied only once, with High Performance
Performance Comparison:
The abscissa is the number of Connections, the Dead Connections is the software name, And the ordinate is the number of Connections processed at this time.
It can be seen that epoll has stable performance and better performance.
Detailed Process Discussion:
Here we will only discuss the general principle. The specific implementation of different languages varies. (Not because I did not do it, not because)
First. In the multiplexing model, each socket is generally set to non-blocking. However, the entire user's process is actually always block.
That is, user processes are blocked by select and poll, but select and poll are not blocked. They are constantly polling and hanging up to complete the work.
Select:
1. Copy fd_set from user State to kernel space (tell the kernel socket to be listened on)
2. register the callback function pollwait (the process is mounted to the waiting queue, when the socket is ready (execute the mask status code to determine), and then wake up the process)
3. the kernel traverses fd and calls every poll method (essentially the pollwait callback function. The returned value is the mask status mask of the socket. That is, if it is ready, assign a value to fd_set)
4. When there is no read/write mask code (there is no prepared), select sleep, wait for the sleep time to reach, and then wake up again to poll fd-set
5. If there is a value, return fd_set (the value has been assigned, for example, the value that can be read is 1) and copy it to the user space.
6. User Process Loop fd_set,
Analysis:
The above process must be executed in each loop,
Copy fi_set twice in a loop, that is, each listener re-notifies the kernel of the event to be monitored, which is a huge overhead when the number of users is large.
Return all fd_set, but do not tell the process which is completed. The process has to be judged cyclically. When the number of users is large (100,000, million), the performance is too low.
Therefore, select only supports 1024 connections.
This also explains why the larger the number of connections, the lower the performance. This is especially true in scenarios where high concurrency and low activity are used for processing inactive connections and loop judgment.
Poll:
Changing the fd_set structure to the pollfd structure can be unlimited, but other problems can be solved.
Epoll:
Improvement:
Fd is copied only once (it tells all kernel registration events and listens to objects at the beginning ).
Returns only the linked list containing all the changed fd values.
Unlimited connection
Epoll provides three functions
Epoll_create (handle), with the size parameter at the beginning, indicating the number of fd. Now the kernel is dynamically allocated,
Epoll_ctl (register event type), register listener events
Epoll_wait (wait for the event to happen), capture the fd signal,
Summary of the three differences:
The select and poll twins have many disadvantages, with few advantages and few application scenarios. Is the product of the Times
Epoll is an advanced version, but only Linux has,
Analyze the specific situation.
4. asynchronous io
Explanation: The process is completely non-congested. when the request is sent, it will do other things. When all the data is ready, the kernel will send a message to the process, and the process will continue to process it,
Implementation: I have heard that it is complicated and I have not studied it.
Iv. Summary and mining
The concepts of some operating systems, I/O models, and the differences of select, poll, and epoll are studied,
There is time for specific implementation and operations, and there may be errors in many details. After the level rises, you can modify the details.