The Python asynchronous IO coroutine: asyncio use different methods to achieve coroutine

Introduction: In the last chapter we introduced the use from the source to the yield from the async, and finally to implement coroutines asyncio.wait () method, let's implement coroutine different control structures, let us look they look at it ~ effect different
linear control flow in the plurality of coroutine easily managed through built-in keyword await. Use asyncio module more complicated structure can be achieved, it can be done concurrently plurality coroutine.

一、asyncio.wait()

You may be a separate operation into multiple parts and executed, and wait (tasks) may be used to set an event to be interrupt tasks (Tasks) circulating to the polling task, other background until completion of the operation of the coroutine woken up.

import time
import asyncio
async def taskIO_1():
    print('开始运行IO任务1...')
    await asyncio.sleep(2)  # 假设该任务耗时2s
    print('IO任务1已完成,耗时2s')
    return taskIO_1.__name__
async def taskIO_2():
    print('开始运行IO任务2...')
    await asyncio.sleep(3)  # 假设该任务耗时3s
    print('IO任务2已完成,耗时3s')
    return taskIO_2.__name__
async def main(): # 调用方
    tasks = [taskIO_1(), taskIO_2()]  # 把所有任务添加到task中
    done,pending = await asyncio.wait(tasks) # 子生成器
    for r in done: # done和pending都是一个任务,所以返回结果需要逐个调用result()
        print('协程无序返回值:'+r.result())

if __name__ == '__main__':
    start = time.time()
    loop = asyncio.get_event_loop() # 创建一个事件循环对象loop
    try:
        loop.run_until_complete(main()) # 完成事件循环,直到最后一个任务结束
    finally:
        loop.close() # 结束事件循环
    print('所有IO任务总耗时%.5f秒' % float(time.time()-start))

Execution results are as follows:

开始运行IO任务1...
开始运行IO任务2...
IO任务1已完成,耗时2s
IO任务2已完成,耗时3s
协程无序返回值:taskIO_2
协程无序返回值:taskIO_1
所有IO任务总耗时3.00209

[Explain]: wait () official documentation used as follows:

done, pending = await asyncio.wait(aws)

Here run concurrently passed aws (awaitable objects), and returns a tuple containing (done, pending) by await, done indicates that the task list has been completed, pending indicates that the task list is not complete.
Note:
① only possible when to generate a list of pending wait () passed timeout parameters.
② returning the result set is arranged in order to complete the task by the event loop wait (), so it tends to the original order of the different tasks.

二、asyncio.gather()

If you are only concerned about the outcome of coroutines run concurrently collection, you can use the gather (), which returns only one result set not only by await, and the result is the order of the result set of the original order of the incoming task.

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:579817333 
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
import time
import asyncio
async def taskIO_1():
    print('开始运行IO任务1...')
    await asyncio.sleep(3)  # 假设该任务耗时3s
    print('IO任务1已完成,耗时3s')
    return taskIO_1.__name__
async def taskIO_2():
    print('开始运行IO任务2...')
    await asyncio.sleep(2)  # 假设该任务耗时2s
    print('IO任务2已完成,耗时2s')
    return taskIO_2.__name__
async def main(): # 调用方
    resualts = await asyncio.gather(taskIO_1(), taskIO_2()) # 子生成器
    print(resualts)

if __name__ == '__main__':
    start = time.time()
    loop = asyncio.get_event_loop() # 创建一个事件循环对象loop
    try:
        loop.run_until_complete(main()) # 完成事件循环,直到最后一个任务结束
    finally:
        loop.close() # 结束事件循环
    print('所有IO任务总耗时%.5f秒' % float(time.time()-start))

Execution results are as follows:

开始运行IO任务2...
开始运行IO任务1...
IO任务2已完成,耗时2s
IO任务1已完成,耗时3s
['taskIO_1', 'taskIO_2']
所有IO任务总耗时3.00184

[Explain]: gather () returns a result set directly by await the list, we can clearly see from the results, although the task 2 is completed first, but the order to return the final result set is the initial order of the incoming task row.

三、asyncio.as_completed()

as_completed (tasks) is a generator that manages a coroutine list (here is the incoming tasks) to run. When the task set lead in a task is finished, it will be the first mission to return the results await keyword. Visible order and return the result wait (), as are arrayed in order to complete the task.

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:579817333 
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
import time
import asyncio
async def taskIO_1():
    print('开始运行IO任务1...')
    await asyncio.sleep(3)  # 假设该任务耗时3s
    print('IO任务1已完成,耗时3s')
    return taskIO_1.__name__
async def taskIO_2():
    print('开始运行IO任务2...')
    await asyncio.sleep(2)  # 假设该任务耗时2s
    print('IO任务2已完成,耗时2s')
    return taskIO_2.__name__
async def main(): # 调用方
    tasks = [taskIO_1(), taskIO_2()]  # 把所有任务添加到task中
    for completed_task in asyncio.as_completed(tasks):
        resualt = await completed_task # 子生成器
        print('协程无序返回值:'+resualt)

if __name__ == '__main__':
    start = time.time()
    loop = asyncio.get_event_loop() # 创建一个事件循环对象loop
    try:
        loop.run_until_complete(main()) # 完成事件循环,直到最后一个任务结束
    finally:
        loop.close() # 结束事件循环
    print('所有IO任务总耗时%.5f秒' % float(time.time()-start))

Execution results are as follows:

开始运行IO任务2...
开始运行IO任务1...
IO任务2已完成,耗时2s
协程无序返回值:taskIO_2
IO任务1已完成,耗时3s
协程无序返回值:taskIO_1
所有IO任务总耗时3.00300

[Explain]: can be seen from the above procedure using as_completed (tasks), and wait (tasks) in common sequence returns results to complete the order coroutine, which Gather () is just the opposite. The difference is that as_completed (tasks) can return to complete the current real-time results, and wait (tasks) to wait done to return after the end of all the coroutine to get results.

IV Summary

Aws refer to the following: awaitable objects. To wait collection of objects, such as a coroutine is waiting for an object list containing a plurality of a coroutine is aws.

asyncio The main parameter passing Return value sequence await the return value type Function Return Type
wait() aws Coroutine complete sequence (Done, pending) with two tuples task list coroutine
as_completed() aws Coroutine complete sequence Return the original value Iterator
gather() *aws Parameter passing Task Order Return a list of values awaitable
Published 706 original articles · won praise 824 · Views 1.29 million +

Guess you like

Origin blog.csdn.net/sinat_38682860/article/details/105055695