Python3.6-asyncio-协程入门

协程概念

1.协程是单线程。
2.协程比线程轻量,在多任务并发场景下,多任务在单个线程中轮流切换使用CPU,比多线程效率高。
3.因为是单线程,所以不需要考虑线程安全问题。
4.因为是单线程,所以无法利用CPU多核优势,可以配合多进程利用CPU多核满足一些极限场景。

协程关键字

1.async关键字

用来修饰函数,使其成为一个coroutine(协程)对象

async def get_url(url):  # 被async修饰过的函数就是个协程对象,不能用普通函数调用方式调用
    print(threading.current_thread().ident, url)  # 打印出线程ID
    try:
        resp = requests.get(url, timeout=1)
    except(ReadTimeout,ConnectTimeout):
        return 'ReadTimeout OR ConnectTimeout'
    return resp

2.await关键字

  1. await用在修饰IO阻塞代码处,其只能修饰协程对象。
  2. 当阻塞代码运行完毕,await也起到获取其返回结果的作用
async def main(url):
    print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
    r = await get_url(url)  # await只能修饰协程对象
    print(url, r)
    return r

运行协程代码

1.获取事件循环

事件循环相当于开了一个线程,等待将并发的任务集塞到这个线程中执行

loop = asyncio.get_event_loop()     # 获取事件循环

2.获取任务集

tasks = [main(url) for url in urls]  # 生成协程作业列表

3.运行任务

resp = loop.run_until_complete(asyncio.gather(*tasks))  # asyncio.gather()将多个协程任务封装成一个协程任务供循环事件调用
print(resp)     # resp是所有协程对象运行的返回结果,类型是列表

以下是完整代码

声明:这是我对asyncio的个人理解,错误之处欢迎批评指正,谢绝侮辱字眼。

# -*- coding: utf-8 -*-
# -------------------------------------------------------------------------------
# Name:         asyncio
# Description:  
# Author:       CHEN
# Date:         2022/5/9
# -------------------------------------------------------------------------------
import requests
import threading
import asyncio
import time
from requests.exceptions import ReadTimeout,ConnectTimeout


# def run_time(func):
#     def inner(*args, **kwargs):
#         start = time.time()
#         func(*args)
#         print("RUN Time: {}s".format(int(time.time() - start)))
# 
#     return inner


async def get_url(url):  # 被async修饰过的函数就是个协程对象,不能用普通函数调用方式调用
    print(threading.current_thread().ident, url)  # 打印出线程ID
    try:
        resp = requests.get(url, timeout=1)
    except(ReadTimeout,ConnectTimeout):
        return 'ReadTimeout OR ConnectTimeout'
    return resp


async def main(url):
    print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
    r = await get_url(url)  # await只能修饰协程对象
    print(url, r)
    return r


if __name__ == '__main__':
    # asyncio.run(main())   # Python3.7以上才能用这种调用方式
    urls = ['https://www.baidu.com', 'https://github.com/', 'https://about.gitlab.com/']
    loop = asyncio.get_event_loop()     # 获取事件循环
    tasks = [main(url) for url in urls]  # 生成协程作业列表
    resp = loop.run_until_complete(asyncio.gather(*tasks))  # asyncio.gather()将多个协程任务封装成一个协程任务供循环事件调用
    print(resp)     # resp是所有协程对象运行的返回结果,类型是列表
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值