asyncio合并基础到动态协程

import time
import asyncio
import logging
import functools
import nest_asyncio
nest_asyncio.apply() # 需要这个,不然asyncio运行出错
from threading import Thread
logging.basicConfig( # 用日志打印输出信息
    level=logging.INFO,
    format="%(asctime)s %(process)d %(thread)d [*] %(message)s"
)



async def do_some_work(x):
    """
    协程遇到await,事件循环将会挂起该协程,执行别的协程,直到其他的协程也挂起或者执行完毕,再进行下一个协程的执行。
    """
    logging.info(f'等候:{x}秒 ')
    await asyncio.sleep(x) # 模仿协程阻塞
#     return '在{}秒后完成'.format(x)#1.直接用事件循环用于注册协程
    logging.info('在{}秒后完成'.format(x))#2.协程需要动态的添加到事件循环中

def callback(t, future):
    logging.info(f'回调函数:{t},{future.result()}')
    
async def main():
    '''
    创建协程
    协程遇到await,事件循环将会挂起该协程,执行别的协程,直到其他的协程也挂起或者执行完毕,再进行下一个协程的执行。
    '''
    now = lambda : time.time()
    start = now()
    coroutine1 = do_some_work(2)# 一个协程
    coroutine2 = do_some_work(3)# 一个协程
    coroutine3 = do_some_work(4)# 一个协程


    tasks = [# 创建多个协程任务
        asyncio.ensure_future(coroutine1),# pending状态(创建时)
        asyncio.ensure_future(coroutine2),
        asyncio.ensure_future(coroutine3)
    ]
#     直接打印
    dones, pendings = await asyncio.wait(tasks)# 并发 运行一个事件循环(第一种方式)
    
    for task in dones:
        logging.info(f'任务权: {task.result()}')
#     results = await asyncio.gather(*tasks)# 并发 运行一个事件循环(第二种方式)
#     for result in results:
#         logging.info(f'任务权: {result}')
    
    
        

#     不在main协程函数里处理结果,直接返回await的内容
#     return await asyncio.wait(tasks)# (第一种方式)
#     return await asyncio.gather(*tasks)#(第二种方式)
#     for task in asyncio.as_completed(tasks):# (第三种方式)
#         return await task # 一个一个返回结果
    logging.info(f'总花费时间:{now() - start}')


def start_loop(loop):
    asyncio.set_event_loop(loop)
    loop.run_forever()

def more_work(x):
    logging.info('更多的工作 {}'.format(x))
    time.sleep(x)
    logging.info('完成更多的工作 {}'.format(x))
    
if __name__ == '__main__':
    
#     1.直接用事件循环用于注册协程-----------------------------------------------------------
#     loop = asyncio.get_event_loop() # 获取时间循环
    # task.add_done_callback(functools.partial(callback, 2))# 创建协程回调函数


#     loop.run_until_complete(task)# 运行一个事件循环(running状态)
#     loop.run_until_complete(asyncio.wait(tasks))# 并发 运行一个事件循环(第一种方式)
#     loop.run_until_complete(asyncio.gather(*tasks))# 并发 运行一个事件循环(第二种方式)

#     done, pending = loop.run_until_complete(main())# 协程嵌套(封装更多的io操作过程)
#     for task in dones:#(第一种方式)
#         logging.info(f'任务权: {task.result()}') # done状态(完成状态)
#     results =loop.run_until_complete(main()) # 协程嵌套(封装更多的io操作过程)
#     for result in results:#(第二种方式)
#         logging.info(f'任务权: {result}')
#     done = loop.run_until_complete(main())# 协程嵌套(封装更多的io操作过程)
#     logging.info(f'任务权: {done}')# (第三种方式)
#     try:
#         loop.run_until_complete(main())
#     except KeyboardInterrupt as e:
#         print(asyncio.Task.all_tasks())
#         print(asyncio.gather(*asyncio.Task.all_tasks()).cancel())
#         loop.stop()
#         loop.run_forever()
#     finally:
#         pass
#         loop.close() # 在jupyter不能手动关闭
#     2.协程需要动态的添加到事件循环中----------------------------------------------------------
#     new_loop = asyncio.new_event_loop()
#     t = Thread(target=start_loop, args=(new_loop,))
#     t.start()
#     new_loop.call_soon_threadsafe(more_work, 6)
#     new_loop.call_soon_threadsafe(more_work, 3)
    asyncio.run_coroutine_threadsafe(do_some_work(6), new_loop)
    asyncio.run_coroutine_threadsafe(do_some_work(4), new_loop)
    

输出:

2019-11-15 13:17:07,695 888 1380 [*] 等候:62019-11-15 13:17:07,695 888 1380 [*] 等候:42019-11-15 13:17:11,696 888 1380 [*]4秒后完成
2019-11-15 13:17:13,698 888 1380 [*]6秒后完成

你可能感兴趣的:(Python,asyncio)