Asyncio is not multi-threaded or multi-process, but runs code in parallel.
Asynchronous execution is supported in JavaScript (browser, Nodejs, Electron, etc.).In earlier versions, they just used the callback function to run other functions after the asynchronous operation completed.But it created the callback problem in JavaScript, so sometime in the last decade they implemented the same async await interface we have in Python 3.6+.The interface looks for users in sequential executions with the same parallel IO efficiency
import asyncioimport timedef write(msg): print(msg, flush=True)async def say1(): await asyncio.sleep(1) write("Hello from 1")async def say2(): await asyncio.sleep(1) write("Hello from 2") write("start")loop = asyncio.get_event_loop()loop.run_until_complete(asyncio.gather( say1(), say2()))write("exit")loop.close()
Run the code, you can see that Hello from 1
runs Hello from 2
after running for 1 second:
$ python asyncoidemo2.py startHello from 1Hello from 2exit
When run_until_complete
runs the say()
function, the interpreter executes the contents of the function line by line.When await
is encountered, the interpreter starts an asynchronous operation: this operation will complete some internal callback operation for the loop, this callback operation is hidden from the developer.But now, as soon as say1
starts, it returns control to the event loop.So, it starts the asynchronous sleep
and control loop, and then the loop has actually started to start the say2
function.
When the first asynchronous sleep
runs for 1 second, enter the internal callback to execute the say1
coroutine, and the next operation is to print Hello from 1
.After printing, it goes back to the active loop again.At the same time, starting from the second sleep, the loop gets events about the completion of the second sleep.
So next Hello from 2
is printed, then the second method also returns.run_until_complete(gather(l1,l2,l3))
will block all l1,l2,l3 Coroutines:
Note that the 7 and 9 events may be swapped - if you run the code multiple times, you may notice that Hello from 1
is printed after Hello from 2
.
event_loop event loop: The program starts an infinite loop, registers some functions to the event loop, and calls the corresponding coroutine function when the event occurs.
coroutine: A coroutine object, which refers to a function defined using the async keyword. Its call will not execute the function immediately, but will return a coroutine object.The coroutine object needs to be registered with the event loop and called by the event loop.
task task: a coroutine object is a natively suspendable function, and a task is a further encapsulation of the coroutine, which includes various states of the task
future: Represents the result of a task that is executed or not executed in the future.It is not fundamentally different from task
async/await keyword: python3.5 keyword used to define coroutine, async defines a coroutine, await is used to suspend blocking asynchronous call interface.
When you need to parallelize multiple CPU operations.Coroutines are only used for IO operations, such as some HTTP clients such as aiohttps
calling the server.
CPU computing operations, such as machine learning, loop over huge arrays to speed up CPU operations.
The most fundamental tool in the Asynchronous Programmer's Toolkit in Python is the new keyword async def
, which is used to declare asynchronous coroutine functions in the same way as that defines normal synchronous functionsdef
is the same.
When we use asyncio, we use a single process thread to execute all tasks simultaneously.asyncio is a neat concept and every data scientist should at least know to make code run faster.A good working knowledge of the process will also help you understand upcoming libraries such as Fastapi, Aiohttp, Aiofiles, Puppeteer, etc.