Python uses the asyncio.create_task() function to run multiple tasks concurrently

This article explains how Python uses asyncio.create_task()functions to run multiple tasks concurrently.

Simulate long-running operations

To simulate long-running operations, you can use asynciothe package's sleep()coroutines. This sleep()function delays for the specified number of seconds:

<span style="background-color:#f8f8f8"><span style="color:#212529"><code class="language-python"><span style="color:#f47067">await</span> asyncio.sleep(seconds)</code></span></span>

Because sleep()it is a coroutine, you need to use awaitkeywords. For example, the following sleep()simulates API calls using coroutines:

import asyncio
async def call_api(message, result=1000, delay=3):
print(message)
await asyncio.sleep(delay)
return result

call_api()is a coroutine. It displays a message, pauses for the specified number of seconds (the default is three seconds), and then returns the result.

The following program is used call_api()twice and measures the time it takes to complete:

import asyncio
import time
async def call_api(message, result=1000, delay=3):
print(message)
await asyncio.sleep(delay)
return result
async def main():
start = time.perf_counter()
price = await call_api('Get stock price of GOOG...', 300)
print(price)
price = await call_api('Get stock price of APPL...', 400)
print(price)
end = time.perf_counter()
print(f'It took { round(end-start,0)} second(s) to complete.')
asyncio.run(main())

output:

Get stock price of GOOG...
300
Get stock price of APPL...
400
It took 6.0 second(s) to complete.

First, start a timer to measure time using timethe module's function:perf_counter()

<span style="background-color:#f8f8f8"><span style="color:#212529"><code class="language-python"> start = time.perf_counter()</code></span></span>

2. Call call_api()the coroutine and display the result:

price = await call_api('Get stock price of GOOG...', 300)
print(price)

3. call_api()The second call:

price = await call_api('Get stock price of APPL...', 400)
print(price)

Finally, show how long the program took to complete:

end = time.perf_counter()
print(f'It took { round(end-start,0)} second(s) to complete.')

Since each call_api()takes three seconds, calling it twice takes six seconds.

In this example, we directly call a coroutine without running it in the event loop. Instead, we get a coroutine object and use awaitthe keyword to execute it and get a result.

We use asyncand awaitto write asynchronous code but it cannot run concurrently, to run multiple operations at the same time we need to use something called tasks.

Introduction to Python tasks

A task is a wrapper around a coroutine that schedules the coroutine to run on the event loop as soon as possible.

Scheduling and execution occurs in a non-blocking fashion, and tasks can be created and other code executed immediately while the task is running.

Note that a task is different from awaita keyword that blocks the entire coroutine until the operation completes and produces a result.

The important thing is that multiple tasks can be created and scheduled to run simultaneously in the event loop at once.

To create a task, a coroutine needs to be passed to asynciothe package's create_task()function. This create_task()function returns an Taskobject.

The following program illustrates how to create two call_api()tasks that schedule and execute coroutines:

import asyncio
import time
async def call_api(message, result=1000, delay=3):
print(message)
await asyncio.sleep(delay)
return result
async def main():
start = time.perf_counter()
task_1 = asyncio.create_task(
call_api('Get stock price of GOOG...', 300)
)
task_2 = asyncio.create_task(
call_api('Get stock price of APPL...', 300)
)
price = await task_1
print(price)
price = await task_2
print(price)
end = time.perf_counter()
print(f'It took { round(end-start,0)} second(s) to complete.')
asyncio.run(main())

output:

Get stock price of GOOG...
Get stock price of APPL...
300
300
It took 3.0 second(s) to complete.

await It is important to use the keyword await for a task at some point in the program  .

If we don't use  await the keyword, Python will schedule the task to run but asyncio.run()stop it when the event loop is closed.

The following figure illustrates the execution flow of the program:

Finally, show main()how long the function took to complete:

end = time.perf_counter()
print(f'It took { round(end-start,0)} second(s) to complete.')

By using this create_task()function, the program is much faster. The more tasks you run, the faster it will be.

Run other tasks while waiting

While  call_api running, other tasks can be run. For example, the following program  call_api displays a message every second while waiting for a task:

import asyncio
import time
async def call_api(message, result=1000, delay=3):
print(message)
await asyncio.sleep(delay)
return result
async def show_message():
for _ in range(3):
await asyncio.sleep(1)
print('API call is in progress...')
async def main():
start = time.perf_counter()
message_task = asyncio.create_task(
show_message()
)
task_1 = asyncio.create_task(
call_api('Get stock price of GOOG...', 300)
)
task_2 = asyncio.create_task(
call_api('Get stock price of APPL...', 300)
)
price = await task_1
print(price)
price = await task_2
print(price)
await message_task
end = time.perf_counter()
print(f'It took { round(end-start,0)} second(s) to complete.')
asyncio.run(main())

output:

Get stock price of GOOG...
Get stock price of APPL...
API call is in progress...
API call is in progress...
API call is in progress...
300
300

Summarize

  • A task is a wrapper around a coroutine that schedules the coroutine to run on the event loop as soon as possible.
  • Create tasks using asynciolibrary functions.create_task()
  • Use the keyword task with the task at some point in the program awaitso that asyncio.run()the task can be completed before the function closes the event loop.

Guess you like

Origin blog.csdn.net/qq_41221596/article/details/131603112