Add another theoretical analysis with high handwriting to facilitate a deeper understanding.
From: http://blog.csdn.net/historyasamirror/article/details/5778378
========================================================== ==================================
What are the differences between synchronous I/O and asynchronous I/O, blocking I/O, and non-blocking I/O? Different people may give different answers to this question. For example, wiki considers asynchronous Io and non-blocking Io as one thing. This is because different people have different knowledge backgrounds and the context is different when discussing this issue. Therefore, to better answer this question, I will first limit the context of this article.
The background of this article is network IO in Linux.
The most important reference in this article is Richard Stevens's"UNIX®Network Programming Volume 1, third edition: The sockets networking", Section 6.2"I/O models", This section describes in detail the characteristics and differences of various Io. If the English is good enough, it is recommended to read it directly. Steven S's style is famous for its depth, so you don't have to worry about it. The flowchart in this article is also taken from references.
In this article, Steven s compares five Io models:
Blocking Io
Nonblocking Io
Io multiplexing
Signal driven Io
Asynchronous Io
Because signal driven Io is not commonly used in practice, I will only mention the remaining four Io models.
Let's talk about the objects and steps involved when I/O occurs.
For a network io (Here we use read as an example), it involves two system objects, one is to call the IO process (or thread), and the other is the system kernel (kernel ). When a read operation occurs, it goes through two phases:
1. Waiting for data preparation (waiting for the data to be ready)
2. Copy data from the kernel to the process (copying the data from the kernel to the process)
It is important to remember these two points, because the differences between these Io models are different in the two phases.
Blocking Io
In Linux, all sockets are blocking by default. A typical read operation process is like this:
When the user process calls the recvfrom system call, the kernel starts the first stage of IO: Prepare data. For Network Io, data has not arrived at the beginning (for example, a complete UDP packet has not yet been received). At this time, the kernel will wait for enough data to arrive. On the user process side, the whole process will be blocked. When the kernel waits until the data is ready, it will copy the data from the kernel to the user memory, and then the kernel returns the result, the user process will unblock the status and run it again.
Therefore, the feature of blocking Io is that it is blocked in both stages of Io execution.
Non-blocking Io
In Linux, you can set socket to non-blocking. When a read operation is performed on a non-blocking socket, the process looks like this:
It can be seen that when a user process sends a read operation, if the data in the kernel is not ready, it does not block the user process, but immediately returns an error. From the perspective of the user process, after initiating a read operation, it does not need to wait, but immediately gets a result. When the user process determines that the result is an error, it knows that the data is not ready, so it can send the read operation again. Once the data in the kernel is ready and the system call of the user process is received again, it immediately copies the data to the user memory and returns it.
Therefore, the user process needs to actively ask about the kernel data.
Io multiplexing
Io multiplexing may be a bit unfamiliar, but if I say select or epoll, I will probably understand it. This Io method is also called Event Driven IO in some places. We all know that the benefit of select/epoll is that a single process can process the IO of multiple network connections at the same time. The basic principle of this function is that the select/epoll function will continuously poll all the sockets in charge. When a socket has data, it will notify the user process. Its Process
When a user process calls the SELECT statement, the entire process will be blocked. At the same time, the kernel will "Monitor" All sockets under the SELECT statement. When the data in any socket is ready, select returns. At this time, the user process then calls the read operation to copy data from the kernel to the user process.
This graph is not much different from the blocking Io graph. In fact, it is worse. Because two system calls (select and recvfrom) need to be used here, while blocking Io only calls one System Call (recvfrom ). However, the advantage of using select is that it can process multiple connections at the same time. (More. Therefore, if the number of connections to be processed is not very high, the web server using select/epoll may not have better performance than the Web server using multi-threading + Blocking Io, and may have a greater latency. The advantage of select/epoll is not that it can process a single connection faster, but that it can process more connections .)
In the I/O multiplexing model, in practice, each socket is generally set to non-blocking. However, as shown in, the entire user's process is always blocked. However, process is block by the Select function, rather than block by socket Io.
Asynchronous I/O
In Linux, asynchronous Io is rarely used. Let's take a look at its process:
After the user process initiates the read operation, it can immediately start to do other things. On the other hand, from the perspective of kernel, when it receives an asynchronous read, it will first return immediately, so it will not generate any block to the user process. Then, the kernel will wait for the data preparation to complete and then copy the data to the user memory. After all this is done, the kernel will send a signal to the user process to tell it that the read operation is complete.
So far, four I/O models have been introduced. Now let's look back at the first few questions: What is the difference between blocking and non-blocking? What is the difference between synchronous Io and asynchronous io.
Answer the simplest one: Blocking vs non-blocking. The difference between the two is clearly described in the previous introduction. Calling blocking Io will block the corresponding process until the operation is completed, while non-blocking Io will return immediately when the kernel still prepares data.
Before describing the differences between synchronous Io and asynchronous Io, you must first define the two. The definitions provided by Steven S (actually the POSIX definition) are like this:
A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes;
An asynchronous I/O operation does not cause the requesting process to be blocked;
The difference between the two is that synchronous Io blocks process when performing "Io operation. According to this definition, the previously described blocking Io, non-blocking Io, and Io multiplexing all belong to synchronous Io. Some may say that non-blocking Io is not blocked. Here is a very "Tricky" place. The "Io operation" in the definition refers to the real Io operation, that is, the recvfrom system call in the example. When non-blocking Io executes the recvfrom system call, if the kernel data is not ready, the process will not be blocked. However, when the data in the kernel is ready, recvfrom will copy the data from the kernel to the user memory. At this time, the process is blocked. During this time, the process is blocked. Asynchronous Io is different. When a process initiates an I/O operation, it directly returns the result and ignores it again until the kernel sends a signal telling the process that I/O is complete. In this process, the process is not blocked at all.
Comparison of Io models:
After the above introduction, we will find that the difference between non-blocking Io and asynchronous Io is quite obvious. In non-blocking Io, although the process is not blocked for most of the time, it still requires the process to take the initiative to check, and after the data preparation is complete, the process also needs to actively call recvfrom again to copy data to the user memory. Asynchronous Io is completely different. It is like a user process handing over the entire Io operation to another person (kernel) to complete, and then the other person will send a signal after completion. During this period, the user process does not need to check the I/O operation status or actively copy data.
Finally, let's take a few examples that are not very appropriate to illustrate these four Io models:
There are four people A, B, C, and D fishing:
A uses the oldest fishing rod, so you have to keep it. When the fish are hooked up, draw a lever;
B's fishing rod has a function to show whether there is a fish bait. So B chats with the MM next to it and checks whether there is a fish bait. If yes, the rod can be quickly pulled;
C's fishing rod is similar to B's, but he thought of a good way: put several fishing rods at the same time, and then stay next to it. Once there is a display that the fish are hooked, it pulls the corresponding fishing rod;
D is a rich man. He simply hired a man to help him fish. Once the man caught the fish, he sent a text message to D.