Before learning asyncio, first clarify the concept of synchronization/asynchronous:
Synchronization refers to the logic of completing the transaction. The first transaction is executed first. If it is blocked, it will wait until the transaction is completed, and then execute the second transaction, in order
Asynchrony is the opposite of synchronization. Asynchrony means that after processing the calling transaction, it does not wait for the processing result of this transaction, and directly processes the second transaction, and informs the caller of the processing result through status, notification, and callback.
asyncio function:
Asynchronous IO adopts a message loop mode, repeating the process of "reading messages-processing messages", which means that the asynchronous IO model "needs a message loop, in which the main thread repeats "reading messages-processing messages" This process.
event_loop: The program opens an infinite loop, and the programmer will register some functions to the event loop. When a satisfying event occurs, the corresponding coroutine function is called.
coroutine: A coroutine object refers to a function defined with the async keyword. Its call will not execute the function immediately, but will return a coroutine object. The coroutine object needs to be registered in the event loop and called by the event loop.
task task: A coroutine object is a function that can be suspended natively, and a task further encapsulates the coroutine, which contains various states of the task.
async/await keyword: A keyword used to define a coroutine, async defines a coroutine, and await is used to suspend a blocked asynchronous call interface.
One, asyncio
Let's take an example to compare the difference between synchronous code and asynchronous code writing. Next, look at the performance gap between the two. Use asyncio.sleep(1) to simulate an io operation that takes 1 second.
Synchronization code:
import time
def hello():
time.sleep(1)
def run():for i inrange(5):hello()print('Hello World:%s'% time.time())if __name__ =='__main__':run()
Hello World:1536842494.2786784
Hello World:1536842495.2796268
Hello World:1536842496.2802596
Hello World:1536842497.2804587
Hello World:1536842498.2812462
Asynchronous code:
import time
import asyncio
# Define asynchronous functions
async def hello():print('Hello World:%s'% time.time())
# Await must be used, yieldfrom cannot be used; if yieldfrom is used, [email protected] corresponds
await asyncio.sleep(1)print('Hello wow World:%s'% time.time())
def run():
tasks =[]for i inrange(5):
tasks.append(hello())
loop.run_until_complete(asyncio.wait(tasks))
loop = asyncio.get_event_loop()if __name__ =='__main__':run()
Hello World:1536855050.1950748
Hello World:1536855050.1950748
Hello World:1536855050.1950748
Hello World:1536855050.1960726
Hello World:1536855050.1960726(Pause for about 1 second)
Hello wow World:1536855051.1993241
Hello wow World:1536855051.1993241
Hello wow World:1536855051.1993241
Hello wow World:1536855051.1993241
Hello wow World:1536855051.1993241
async def is used to define asynchronous functions, which have asynchronous operations inside. Each thread has an event loop. When the main thread calls asyncio.get_event_loop(), it creates an event loop, and throws asynchronous tasks to the run_until_complete() method of this loop. The event loop will arrange the execution of the cooperative program.
In the above program, hello() will first print out Hello world!, and then, the yield from syntax allows us to conveniently call another generator.
Since await asyncio.sleep(1) is also a coroutine, the thread will not wait for asyncio.sleep(1), but directly interrupt and execute the next message loop.
When asyncio.sleep(1) returns, the thread can get the return value from yield from (here it is None), and then execute the next line of statements.
Consider asyncio.sleep(1) as an IO operation that takes 1 second. During this period, the main thread does not wait, but executes other executable coroutines in EventLoop, so concurrent execution can be achieved.
**Summary of asyncio operations: **
async def hello(): define async asynchronous function, you can add await async.sleep(N) in the middle to set interrupt and execute the next loop message
tasks = [] The task is to further encapsulate the coroutine, which contains various states of the task. That is, multiple coroutine functions can be encapsulated into a set of Task and then executed concurrently
loop = asyncio.get_event_loop() #Get the "event loop" object
loop.run_until_complete(asyncio.wait(tasks)) #Call the coroutine function through the event loop
loop.close() End time loop
Two, aiohttp
If you need concurrent http requests, usually requests are used, but requests are a synchronous library. If you want to be asynchronous, you need to introduce aiohttp.
Here to introduce a class, from aiohttp import ClientSession, first create a session object, and then use the session object to open the web page.
The session can perform multiple operations, such as post, get, put, head, etc.
Basic usage:
async with ClientSession() as session:
async with session.get(url) as response:
Example of aiohttp asynchronous implementation:
import asyncio
from aiohttp import ClientSession
tasks =[]
url ="https://www.baidu.com/{}"async def hello(url):asyncwithClientSession()as session:asyncwith session.get(url)as response:
response =await response.read()print(response)if __name__ =='__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(hello(url))
First of all, the async def keyword defines that this is an asynchronous function. The await keyword is added in front of the operation that needs to be waited. Response.read() waits for the request response, which is an IO-consuming operation. Then use the ClientSession class to initiate an http request.
Multi-link asynchronous access
What if we need to request multiple URLs? To access multiple URLs synchronously, just add a for loop. But the asynchronous implementation is not so easy. On the basis of the previous, you need to wrap hello() in the Future object of asyncio, and then pass the list of Future objects to the event loop as a task.
import time
import asyncio
from aiohttp import ClientSession
tasks =[]
url ="https://www.baidu.com/{}"async def hello(url):asyncwithClientSession()as session:asyncwith session.get(url)as response:
response =await response.read()print('Hello World:%s'% time.time())
def run():for i inrange(5):
task = asyncio.ensure_future(hello(url.format(i)))
tasks.append(task)if __name__ =='__main__':
loop = asyncio.get_event_loop()run()
loop.run_until_complete(asyncio.wait(tasks))
Hello World:1536843566.064149
Hello World:1536843566.070586
Hello World:1536843566.0769563
Hello World:1536843566.0779328
Hello World:1536843566.0799286
·Collect http response
Well, the above introduced the asynchronous implementation of accessing different links, but we just sent a request. If we want to collect the responses one by one into a list, and finally save it locally or print it out, how to achieve it, you can use asyncio.gather (*tasks) Collect all responses
import time
import asyncio
from aiohttp import ClientSession
tasks =[]
url ="https://www.baidu.com/{}"async def hello(url):asyncwithClientSession()as session:asyncwith session.get(url)as response:
# print(response)print('Hello World:%s'% time.time())returnawait response.read()
def run():for i inrange(5):
task = asyncio.ensure_future(hello(url.format(i)))
tasks.append(task)
result = loop.run_until_complete(asyncio.gather(*tasks))print(result)if __name__ =='__main__':
loop = asyncio.get_event_loop()run()
Hello World:1536843488.678779
Hello World:1536843488.6797836
Hello World:1536843488.6867576
Hello World:1536843488.6877556
Hello World:1536843488.6877556
The above instructions for using the python asynchronous async library are all the content shared by the editor. I hope to give you a reference.