Python learning-asynchronous IO

In the IO programming section, we already know that the speed of CPU is much faster than IO such as disk and network. In a thread, the CPU executes code extremely fast. However, once it encounters IO operations, such as reading and writing files, sending network data**, it needs to wait for the IO operation to complete before proceeding to the next step. This situation is called synchronous IO**.

During the IO operation, the current thread is suspended, and other codes that need to be executed by the CPU cannot be executed by the current thread.

Because an IO operation blocks the current thread , causing other code to be unable to execute, we must use multiple threads or multiple processes to execute code concurrently to serve multiple users. Each user will allocate a thread. If the thread is suspended due to IO, the threads of other users will not be affected.

Although the multi-thread and multi-process model solves the concurrency problem, the system cannot increase threads without limit. Because the overhead of switching threads in the system is also high, once the number of threads is too large, the CPU time is spent on thread switching, and the time to actually run the code is less, resulting in a serious performance degradation .

Since the problem we want to solve is a serious mismatch between the high-speed execution capability of the CPU and the turtle speed of the IO device, multi-threading and multi-process are just a way to solve this problem.

Another way to solve the IO problem is asynchronous IO. When the code needs to perform a time-consuming IO operation, it only issues an IO instruction, does not wait for the IO result, and then executes other code. After a period of time, when the IO returns the result, it will notify the CPU for processing.

It is conceivable that if the code written in normal order is actually unable to complete asynchronous IO

do_some_code()
f = open('/path/to/file', 'r')
r = f.read() # <== 线程停在此处等待IO操作结果
# IO操作完成后线程才能继续执行:
do_some_code(r)

Therefore, the code of the synchronous IO model cannot implement the asynchronous IO model.

The asynchronous IO model requires a message loop . In the message loop, the main thread repeats the process of "reading messages-processing messages ":

loop = get_event_loop()
while True:
    event = loop.get_event()
    process_event(event)

The message model is actually used in desktop applications as early as possible. The main thread of a GUI program is responsible for reading and processing messages continuously. All keyboard, mouse and other messages are sent to the message queue of the GUI program, and then processed by the main thread of the GUI program.

Because the GUI thread processes messages such as keyboards and mice very fast, the user does not feel the delay. Sometimes, **GUI thread encounters a problem in the process of processing a message, which causes a message processing time to be too long. **At this time, the user will feel that the entire GUI program stops responding, and there is no response when typing on the keyboard or clicking the mouse. . This situation shows that in the message model, a message must be processed very quickly, otherwise, the main thread will not be able to process other messages in the message queue in time, causing the program to appear to stop responding .

How does the message model solve the problem that synchronous IO must wait for IO operations? When encountering an IO operation, the code is only responsible for issuing an IO request, without waiting for the IO result, and then directly ends this round of message processing and enters the next round of message processing. When the IO operation is completed, you will receive a "IO complete" message, and you can directly obtain the IO operation result when processing the message.

In the period from "Issuing IO request" to receiving "IO completion", under the synchronous IO model, the main thread can only be suspended , but under the asynchronous IO model, the main thread does not rest, but continues in the message loop. Process other messages . In this way, under the asynchronous IO model, one thread can process multiple IO requests at the same time, and there is no operation to switch threads. For most IO-intensive applications, using asynchronous IO will greatly enhance the system's multitasking capabilities.

Guess you like

Origin blog.csdn.net/qq_44787943/article/details/112641359