美文网首页
python进阶-14-协程 | 异步IO

python进阶-14-协程 | 异步IO

作者: 西海岸虎皮猫大人 | 来源:发表于2020-09-23 22:40 被阅读0次
# coding=utf-8
# 协程
# 用户态的轻量级线程
# 执行过程可能随时中断
# 协程拥有自己的寄存器上下文和栈,记录上一次离开时位置
# 无需线程上下文开销,避免无意义调度
# 程序员承担调度责任
# 协程失去标准线程多CPU能力
# 无需原子锁
# 单CPU上万协程不是问题

# 缺点:
# 1.无法利用多核CPU,需要与进程线程搭配
# 2.会阻塞整个程序

# 协程通过generator实现
# yield可看做return

# def foo():
#     print('starting...')
#     while True:
#         # 函数使用yield,则该函数就成为一个生成器
#         # 类似notify
#         res = yield 4
#         print('res:', res)
# g = foo()
# print(type(g))
# print(next(g))
# print('*'*20)

# 使用yield实现协程
# import time
# def A():
#     while True:
#         print('-----------A----------')
#         yield
#         time.sleep(0.5)
# def B(c):
#     while True:
#         print('-----------B----------')
#         c.__next__()
#         time.sleep(0.5)
#
# a = A()
# B(a)

# send发送参数
# def foo():
#     print('starting...')
#     while True:
#         res = yield 4
#         print(res)
#
# g = foo()
# print(next(g))
# # print(next(g))
# # send发送参数
# print(g.send(10))

# 生产者 消费者
# def produce(c):
#     for i in range(1, 10):
#         print('生产者生产产品: %d'%i)
#         c.send(str(i))
# def consume():
#     while True:
#         res = yield
#         print('消费者消费产品:' + res)
#
# # 生成器对象
# c = consume()
# next(c)
# produce(c)

# 消费者 -> yield中断 -> 生产者 -> send发送数据 -> 消费者


# 异步io
# 协程对象传给事件循环
# io密集型场景
# import time
# now = lambda: time.time()
# def foo():
#     time.sleep(1)
#
# start = now()
# for i in range(5):
#     foo()
# print('花费时间:', now() - start)
#
# import asyncio
# # 协程对象 async定义
# async def foo():
#     asyncio.sleep(1)
#
# start = now()
# # 事件循环
# loop = asyncio.get_event_loop()
# for i in range(5):
#     # RuntimeWarning:
#     loop.run_until_complete(foo())
# print('异步时间:', now() - start)

# import asyncio
# import time
#
# now = lambda: time.time()
# start = now()
# # 协程对象
# async def do_work(x):
#     print('waiting...', x)
# # 事件循环
# loop = asyncio.get_event_loop()
# # 协程对象加入事件循环
# loop.run_until_complete(do_work(3))
# print('time:', now() - start)


# 创建task
# 对协程的包装
# 可以获取协程运行结果
# import asyncio
# import time
# async def do_work(x):
#     print('waiting...', x)
# coroutine = do_work(3)
# loop = asyncio.get_event_loop()
# # 方式1
# # task = asyncio.ensure_future(coroutine)
# # 方式2
# task = loop.create_task(coroutine)
# # 打印任务状态
# # print(task)
# # task是asyncio.Future子类
# print(isinstance(task, asyncio.Future))
# loop.run_until_complete(task)
# # print(task)

# 绑定回调
# import asyncio
# import time
# async def do_work(x):
#     print('waiting...', x)
#     return 'Done after {}s'.format(x)
# coroutine = do_work(3)
# loop = asyncio.get_event_loop()
# task = loop.create_task(coroutine)
# def callback(future):
#     # todo 没获取到结果
#     print('callback:', future.result())
# loop.run_until_complete(task)
# # task.add_done_callback(callback)
# # 直接调用task中的result获取返回结果
# print(task.result())


# 阻塞和await
# 协程遇到await则挂起
# import asyncio
# import time
# async def do_work(x):
#     print('waiting...', x)
#     # 遇到耗时操作直接执行其他结果
#     await asyncio.sleep(x)
#     return 'Done after {}s'.format(x)
# now = lambda: time.time()
# start = now()
# coroutine = do_work(3)
# loop = asyncio.get_event_loop()
# task = asyncio.ensure_future(coroutine)
# loop.run_until_complete(task)
# print(task.result())
# print('time:', now() - start)


# 并发和并行
# 并发 多个人 并行 多件事
# 多个协程完成任务
# import asyncio
# import time
#
# async def do_work(x):
#     print('waiting...', x)
#     # 遇到耗时操作直接执行其他结果
#     await asyncio.sleep(x)
#     return 'Done after {}s'.format(x)
# now = lambda: time.time()
# start = now()
# coroutine1 = do_work(1)
# coroutine2 = do_work(2)
# coroutine3 = do_work(4)
# tasks = [
#     asyncio.ensure_future(coroutine1),
#     asyncio.ensure_future(coroutine2),
#     asyncio.ensure_future(coroutine3)
# ]
# loop = asyncio.get_event_loop()
# loop.run_until_complete(asyncio.wait(tasks))
# for task in tasks:
#     print(task.result())
# print('time:', now() - start)


# 协程嵌套
# 多个协程放在函数中,该函数为协程对象
# import asyncio
# import time
#
# async def do_work(x):
#     print('waiting...', x)
#     # 遇到耗时操作直接执行其他结果
#     await asyncio.sleep(x)
#     return 'Done after {}s'.format(x)
#
# # 任务列表封装协程对象
# async def main():
#     coroutine1 = do_work(1)
#     coroutine2 = do_work(2)
#     coroutine3 = do_work(4)
#     tasks = [
#         asyncio.ensure_future(coroutine1),
#         asyncio.ensure_future(coroutine2),
#         asyncio.ensure_future(coroutine3)
#     ]
#     # 获取结果方式1:
#     # dones, pendings = await asyncio.wait(tasks)
#     # for task in dones:
#     #     print(task.result())
#
#     # 获取结果方式2:
#     # results = await asyncio.gather(*tasks)
#     # for result in results:
#     #     print(result)
#
#     # return await asyncio.gather(*tasks)
#
#     # 获取结果方式4:
#     # return await asyncio.wait(tasks)
#
#     # 获取结果方式5:
#     for task in asyncio.as_completed(tasks):
#         result = await task
#         print(result)
# now = lambda: time.time()
# start = now()
# loop = asyncio.get_event_loop()
# # 异常: sys:1: RuntimeWarning: coroutine 'main' was never awaited todo
# # loop.run_until_complete(asyncio.wait(main()))
# # 获取结果方式3:
# # results = loop.run_until_complete(main())
# # for result in results:
# #     print(result)
#
# # dones,pending = loop.run_until_complete(main())
# # for task in dones:
# #     print(task.result())
#
# loop.run_until_complete(main())
# print('time:', now() - start)


# 协程停止
# 状态: pending running done cancelled
import asyncio
import time
async def do_work(x):
    print('waiting...', x)
    # 遇到耗时操作直接执行其他结果
    await asyncio.sleep(x)
    return 'Done after {}s'.format(x)

coroutine1 = do_work(1)
coroutine2 = do_work(2)
coroutine3 = do_work(4)
tasks = [
        asyncio.ensure_future(coroutine1),
        asyncio.ensure_future(coroutine2),
        asyncio.ensure_future(coroutine3)
]
now = lambda: time.time()
start = now()
loop = asyncio.get_event_loop()
try:
    loop.run_until_complete(asyncio.wait(tasks))
except KeyboardInterrupt as e:
    print(asyncio.Task.all_tasks())
    for task in asyncio.Task.all_tasks():
        # 返回true代表当前任务取消成功
        print(task.cancel())
        loop.stop()
        loop.run_forever()
finally:
    loop.close()
# 命令行运行, 异常: SyntaxError: Non-ASCII character '\xe5'
print('time:', now() - start)

相关文章

网友评论

      本文标题:python进阶-14-协程 | 异步IO

      本文链接:https://www.haomeiwen.com/subject/upfayktx.html