IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> python中async/await的理解和使用 -> 正文阅读

[Python知识库]python中async/await的理解和使用

进程、线程、协程

进程

进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。
通俗来说,如下图所示,打开win11的任务管理器,里面的Apifox就是一个进程,Google Chrome谷歌浏览器也是一个进程,微信等等这就是一个进程
在这里插入图片描述

线程

线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在Unix System V及SunOS中也被称为轻量进程(lightweight processes),但轻量进程更多指内核线程(kernel thread),而把用户线程(user thread)称为线程。
通俗来说,如下图所示,打开win11的任务管理器,Pycharm展示的7条就是7个线程,也就是说,一个进程里面有多个线程,这个7个线程不是同步进行的,而是异步,这样的话,就会有上下文切换,浪费时间
在这里插入图片描述

协程

进程和线程是计算机提供的,协程是程序员创造的,不存在于计算机中。这样的话,由程序员控制,就会很方便灵活,
协程(Co-routine),也可称为微线程,或非抢占式的多任务子例程,一种用户态的上下文切换技术(通过一个线程实现代码块间的相互切换执行)
意义:在一个线程(协程)中,遇到io等待时间,线程可以利用这个等待时间去做其他事情

async/await的使用

同步和异步协程的比较

假设有三个任务,里面都有大量的i/o等待时间

同步

import datetime
import time


def test1():
    time.sleep(3)
    print('washing1 finished')


def test2():
    time.sleep(2)
    print('washing2 finshed')


def test3():
    time.sleep(5)
    print('washing3 finshed')


if __name__ == '__main__':
    time1 = datetime.datetime.now()
    test1()
    test2()
    test3()
    time2 = datetime.datetime.now()
    # 0:00:10.032949
    print(time2-time1)

协程

import asyncio
import datetime


async def test1():
    await asyncio.sleep(3)  # 使用 asyncio.sleep(), 它返回的是一个可等待的对象
    print('washer1 finished')


async def test2():
    await asyncio.sleep(2)
    print('washer2 finished')


async def test3():
    await asyncio.sleep(5)
    print('washer3 finished')

if __name__ == '__main__':
    """
        事件循环机制分为以下几步骤:
            1. 创建一个事件循环
            2. 将异步函数加入事件队列
            3. 执行事件队列, 直到最晚的一个事件被处理完毕后结束
            4. 最后建议用 close() 方法关闭事件循环, 以彻底清理 loop 对象防止误用
        """
    time1 = datetime.datetime.now()

    # 1. 创建一个事件循环
    loop = asyncio.get_event_loop()

    # 2. 将异步函数加入事件队列
    tasks = [
        test1(),
        test2(),
        test3(),
    ]

    # 3. 执行事件队列, 直到最晚的一个事件被处理完毕后结束
    loop.run_until_complete(asyncio.wait(tasks))

    # 4. 如果不再使用 loop, 则关闭
    loop.close()

    time2 = datetime.datetime.now()
    # 0:00:05.009762
    print(time2-time1)

由执行时间可以看到,同步使用了10秒,而协程使用的5秒,可以看出协程的精髓在于,遇到等待即切换,而且没有上下文的损耗,更快,但是注意的是,协程是运行到一个线程里面的,那么,它的缺点就是,无法充分利用多核CPU的特点

python3.6和3.7的区别

python3.6

python3.6需要自己手动创建事件循环
事件循环:去检索一个任务列表的所有任务,并执行所有未执行任务,直至所有任务执行完成

# python 源码
import asyncio

async def func1():
    print('协程1')

async def func2():
    print('协程2')

# task可为列表,即任务列表
# task = func1()
task = [func1(), func2()]
# 创建事件循环
loop = asyncio.get_event_loop()
# 添加任务,直至所有任务执行完成
loop.run_until_complete(asyncio.wait(task))
#关闭事件循环
loop.close()
# 事件循环关闭后,再次调用loop,将不会再次执行。

python3.7

python3.7不需要我们手动创建事件循环,它会自动帮我们创建

相当于同步,只能说明基础语法

import asyncio, datetime

async def func1(name):
    print(name, "启动")
    await asyncio.sleep(2)
    print(name, "关闭")


async def main():
    await func1("动作1")
    await func1("动作2")
    await func1("动作3")


if __name__ == '__main__':
    time1 = datetime.datetime.now()
    asyncio.run(main())
    time2 = datetime.datetime.now()
    # 0:00:06.018858
    print(time2-time1)
    """
    动作1 启动
    动作1 关闭
    动作2 启动
    动作2 关闭
    动作3 启动
    动作3 关闭
    """

改进版

import asyncio
import datetime


async def func1(name):
    print(name, "启动")
    await asyncio.sleep(2)
    print(name, "关闭")


async def main():
    await asyncio.gather(
        asyncio.create_task(func1("动作1")),
        asyncio.create_task(func1("动作2")),
        asyncio.create_task(func1("动作3")),
    )


if __name__ == '__main__':
    time1 = datetime.datetime.now()
    asyncio.run(main())
    time2 = datetime.datetime.now()
    # 0:00:02.006539
    print(time2-time1)
    """
    动作1 启动
	动作2 启动
	动作3 启动
	动作1 关闭
	动作2 关闭
	动作3 关闭
    """

通过上面两个例子打印的时间以及打印字符串的顺序,我们可以看出create_task的作用,虽然还是同步,但是是遇到堵塞就里面启动第二个

异步函数调用异步函数

import asyncio
import datetime

async def func2(name):
    await asyncio.sleep(2)
    print(name, "我是func2")


async def func1(name):
    print(name, "启动")
    await func2(name)
    print(name, "关闭")


async def main():
    await asyncio.gather(
        asyncio.create_task(func1("动作1")),
        asyncio.create_task(func1("动作2")),
        asyncio.create_task(func1("动作3")),
    )


if __name__ == '__main__':
    time1 = datetime.datetime.now()
    asyncio.run(main())
    time2 = datetime.datetime.now()
    # 0:00:02.006539
    print(time2-time1)
    """
    动作1 启动
    动作2 启动
    动作3 启动
    动作1 我是func2
    动作1 关闭
    动作2 我是func2
    动作2 关闭
    动作3 我是func2
    动作3 关闭
    """

由上面的例子可以看出,协程里面调用协程,其步骤是同步的

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 11:52:04  更:2022-10-31 11:53:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/26 3:19:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计