What did the program go through when reading the file?

Source | Coder's Survival on Deserted Island (ID:escape-it)

Have you ever wondered what happens at the bottom of the computer when we perform I/O operations?

Before answering this question, let's take a look at why I/O is extremely important for computers.

What is the computer that cannot perform I/O?

I believe that I/O operations are the most familiar to programmers:

When we use printf in C language, "<<" in C++, print in Python, System.out.println in Java, etc., this is I/O; when we use various languages ​​to read and write files, This is also I/O; when we communicate with the network via TCP/IP, this is also I/O; when we use the mouse to fly in the air, when we pick up the keyboard and give pointers in the comment area, or immerse ourselves in manufacturing When there is a bug, when we can see a beautiful graphical interface on the screen, etc., all of this is I/O.

Think about it, if there is no I/O computer, what a boring device it would be. You can’t watch movies, play games, or surf the Internet. Such a computer is at best a large calculator.

Since I/O is so important, what exactly is I/O?

What is I/O

I/O is a simple data copy , nothing more.

This is very important. In order to deepen everyone's impression, come, Everybody, Follow me, friends on the tree over there, and friends on the wall over there, raise your hands and sing to me. The boundless horizon is. . . Sorry, I/O is just data copy, I/O is just data copy.

Let's put the concert aside first, since it is copying data, where should it be copied from?

If the data is copied from an external device to the memory, this is Input.

If the data is copied from the memory to the external device, this is Output.

Copying data back and forth between memory and external devices is Input and Output, referred to as I/O (Input/Output), nothing more.

I / O given CPU

Now that we know what I/O is, the next step is the important part. Pay attention, and sit down.

We know that the current CPU's main frequency starts at a few GHz. What does this mean? Simply put, the speed at which the CPU executes machine instructions is in the nanosecond level, while the usual I/O such as disk operations, a disk seek is about milliseconds, so if we compare the CPU speed to a fighter jet, then I/O operations The speed is KFC .

That is to say, when our program runs (CPU executes machine instructions), its speed is much faster than I/O speed. Then the next question is that the speed difference between the two is so large, then how do we design, How to use system resources more reasonably and efficiently?

Since there is a speed difference, and the process cannot move forward until the I/O operation is completed, there is obviously only one way, and that is to wait, wait .

The same is waiting. There are smart waiting and silly waiting, referred to as silly waiting. So, should you choose smart waiting or silly waiting?

Suppose you are a rash person (CPU) and need to wait for an important file. Unfortunately, this file can only be delivered by express (I/O). Then you choose to do nothing and look at the door affectionately. Just like Hani looking forward to you, waiting for this courier intently? Or don't worry about the delivery for now, just play a game, watch a movie, watch a short video, and wait for the delivery to come?

Obviously, a better way is to do other things first, and let's talk about it when the express arrives.

Therefore, the key point here is that things on hand before the express delivery can be paused first, switch to other tasks, and switch back when the express delivery arrives .

With this understanding, you can understand what happens at the bottom when performing I/O operations.

Next, let's take reading a disk file as an example to explain this process.

What happens at the bottom level when I/O is performed

In the last article " A Thorough Understanding of Threads and Thread Pools in High Concurrency and High Performance ", we introduced the concept of processes and threads. In operating systems that support threads, threads are actually scheduled instead of processes. To understand the I/O process more clearly, we temporarily assume that the operating system only has the concept of processes, and we don't consider threads first, this will not affect our discussion.

Now there are two processes in the memory, process A and process B. The current process A is running, as shown in the figure:

There is a piece of code to read the file in process A, no matter what language we usually define a buff to load data, and then call functions such as read, like this:

read(buff);

This is a typical I/O operation. When the CPU executes this code, it will send a read request to the disk. Note that compared with the speed at which the CPU executes instructions, I/O operations are very slow, so the operation It is impossible for the system to waste precious CPU computing resources on unnecessary waiting. At this time, the key point is here. Note that the next point is the key point.

Because the external device performs I/O operations very slowly, the process cannot continue to move forward until the I/O operation is completed. This is the so-called blocking , which is commonly referred to as block. After the operating system detects that the process initiates a request to the I/O device, it suspends the process. How to suspend it? Very simple, just record the running status of the current process and point the PC register of the CPU to the instructions of other processes.

When the process is suspended, it will continue to execute. Therefore, the operating system must save the suspended process for subsequent execution. Obviously we can use the queue to save the suspended process. As shown in the figure, the process A is suspended and put In the blocking queue (note that different operating systems have different implementations, and each I/O device may have a corresponding blocking queue, but this difference in implementation details does not affect our discussion).

At this time, the operating system has sent an I/O request to the disk, so the disk driver begins to copy the data from the disk to the buff of process A. Although process A has been suspended at this time, it does not prevent the disk from sending to memory. In copy data. Note that modern disks do not need the help of CPU when copying data to memory. This is called DMA (Direct Memory Access). This process is shown in the figure:

Let the disk copy the data first, and we will continue to talk.

In fact, in addition to the blocking queue, there is also a ready queue in the operating system . The so-called ready queue means that the processes in the queue are ready to be executed by the CPU. You may ask why there must be a ready queue for direct execution? The answer is simple, it is enough to go around , even if only on a core machine can create hundreds of thousands of processes, CPU impossible to perform so many processes simultaneously, so there must be such a process, even if everything is ready Nor can it be allocated to computing resources , and such processes are placed in the ready queue.

Now process B is in the ready queue, everything is ready and only owes CPU, as shown in the figure:

When the execution of process A is suspended, the CPU cannot be idle, because there is still process B waiting to be fed in the ready queue. At this time, the operating system starts to find the next executable process in the ready queue, which is process B here.

At this time, the operating system takes process B out of the ready queue, finds out the location of the machine instruction executed when process B is suspended, and then points the PC register of the CPU to this location, so that process B starts running, as shown in the figure :

Note, note that the next paragraph is the key point in the key.

Pay attention to the above picture. At this time, process B is being executed by the CPU, and the disk is copying data to the memory space of process A. Can you see it? Everyone is busy and no one is idle. Data copy and instruction execution are proceeding at the same time Under the scheduling of the operating system, the CPU and disk are fully utilized. This is where the programmer's wisdom lies.

Now you should understand why the operating system is so important.

After that, the disk finally copied all the data to the memory of process A. At this time, the disk notifies the operating system that the task is complete. You may ask how to notify? This is interruption.

After the operating system receives the disk interrupt, it finds that the data copy is complete, and process A regains the qualification to continue running. At this time, the operating system carefully puts process A from the blocking queue to the ready queue, as shown in the figure:

Note that from the previous discussion on the ready state, we know that the operating system will not directly run process A, and process A must be placed in the ready queue to wait, which is fair to everyone.

After that, the process B continues to execute, and the process A continues to wait. After the process B executes for a while, the operating system thinks that the execution time of the process B is long enough, so it puts the process B in the ready queue, takes the process A out and continues execution.

Note that the operating system puts the process B in the ready queue, so the process B is suspended only because the time slice is up and not because the I/O request is blocked, as shown in the figure:

Process A continues to execute. At this time, the buff is filled with the desired data. Process A runs happily, as if it has never been suspended. The process doesn’t know anything about being suspended. This is The magic of the operating system .

Now you should understand what kind of process I/O is.

This way the process performs I/O operations is blocked and suspended execution is called blocking I/O, blocking I/O, which is also the most common and easy to understand I/O method. There are blocking I/O and non- Blocking I/O, we will not consider this method for now.

At the beginning of this section, we said that we only consider processes and not threads for the time being. Now we relax this condition. It is actually very simple. We only need to change the process scheduled in the previous figure to thread. The discussion here is the same for threads. Established.

Zero-copy

The last thing to note is that in the above explanation, we directly copied the disk data to the process space, but in general, I/O data is first copied to the operating system, and then the operating system is copied to the process space . Therefore, we can see that there is actually a layer of copy through the operating system. For scenarios with high performance requirements, it is actually possible to bypass the operating system and directly perform data copy. This is also the scenario described in this article, which bypasses the operating system directly. The technology for data copy is called Zero-copy , which is a technology commonly used in high-concurrency and high-performance scenarios. The principle is very simple.

to sum up

This article explains the I/O commonly used by programmers. Generally speaking, as programmers, we don’t need to care about it. However, understanding the underlying principles behind I/O is extremely beneficial for designing high-performance and high-concurrency systems. I hope this article will be useful to everyone. A deeper understanding of I/O is helpful.


更多精彩推荐
☞一年翻 3 倍,装机量 6 亿台的物联网操作系统又放大招!
☞乘“峰”而上,聚生态之力共创软件产业新未来
☞腾讯微博即将关停,十年了,你用过吗?
☞Cognitive Inference:认知推理下的常识知识库资源、常识推理测试评估与中文实践项目索引
☞超详细 | 21张图带你领略集合的线程不安全
☞腾讯云区块链邀您参加2020腾讯全球数字生态大会
点分享点点赞点在看

Guess you like

Origin blog.csdn.net/csdnnews/article/details/108525813