zoukankan      html  css  js  c++  java
  • Python 协程实现异步

    今日主题:前面分享过Python 通过使用回调函数如何实现异步的处理,今天我们将通过一个简单的示例来讲解一下协程是如何实现异步的处理的。

    协程的概念
    协程,又称微线程,是一种用户态的轻量级线程。协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置,当程序中存在大量不需要CPU的操作时(IO),适用于协程。

    协程的优势
    协程有极高的执行效率,因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销。不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。因为协程是一个线程执行,所以想要利用多核CPU,最简单的方法是多进程+协程,这样既充分利用多核,又充分发挥协程的高效率。

    构成协程的条件

    • 必须在只有一个单线程里实现并发
    • 修改共享数据不需加锁
    • 用户程序里自己保存多个控制流的上下文栈
    • 一个协程遇到IO操作自动切换到其它协程

    Python 使用协程实现异步

     1import threading
     2import time
     3import datetime
     4
     5#第一个请求
     6def request_1():
     7    print("the request 1 is start")
     8    data=yield io()#定义一个协程处理
     9    print("the response of callback is:",data)
    10   print("the request 1 is end")
    11
    12#第二个请求
    13def request_2():
    14    print("the request 2 is start")
    15    time.sleep(2)#定义耗时2s
    16    print("the request 2 is end")
    17
    18#获取数据请求类的操作,如:从db读取数据,循环耗时,调用其他api等
    19def io():
    20    def run():
    21        print("the run is start")
    22        time.sleep(5)#定义耗时5s
    23        print("the run is end")
    24        conn_db=[x for x in range(10000)] #模拟从db获取数据
    25        try:
    26            global gen
    27            gen.send(conn_db) #线程结束时发送数据给request_1函数里面的data=yeild io(),此时request_1被唤醒继续处理
    28        except StopIteration as e:
    29            print(e)
    30    # 这里是启动一个线程去处理这个io操作,不用阻塞程序的处理,即不影响requst_2的继续处理
    31    threading.Thread(target=run,).start()
    32
    33if __name__ == '__main__':
    34    start_time=datetime.datetime.now()
    35    global gen
    36    gen=request_1() #函数的赋值操作,生成一个生成器
    37    next(gen)#调用next函数,预激协程,执行了request_1()函数,如果io被挂起,就直接执行request_2()
    38    request_2()
    39    end_time=datetime.datetime.now()
    40    #这里是在统计总耗时,从打印的结果可以看到是异步处理的。
    41    print("the spend of total time is:",(end_time-start_time).seconds)

    程序运行后的输出是:

    1 the request 1 is start
    2 the run is start
    3 the request 2 is start
    4 the request 2 is end
    5 the spend of total time is: 2
    6 the run is end
    7 the response of callback is: [0, 1,...9999]
    8 the request 1 is end

    欢迎关注【无量测试之道】公众号,回复【领取资源】,
    Python编程学习资源干货、
    Python+Appium框架APP的UI自动化、
    Python+Selenium框架Web的UI自动化、
    Python+Unittest框架API自动化、

    资源和代码 免费送啦~
    文章下方有公众号二维码,可直接微信扫一扫关注即可。

    备注:我的个人公众号已正式开通,致力于测试技术的分享,包含:大数据测试、功能测试,测试开发,API接口自动化、测试运维、UI自动化测试等,微信搜索公众号:“无量测试之道”,或扫描下方二维码:

     添加关注,让我们一起共同成长!

  • 相关阅读:
    设计模式课程 设计模式精讲 2-1 本章导航
    数字 日期 格式化方法
    jQuery事件委托之Safari失效的解决办法--摘抄
    css3鼠标点击穿透--摘抄
    字符串日期转换为周
    在echars上发布的半圆环形图
    一些框架源码中的代码
    webSQL 增删改查
    Android 根据版本号更新
    Android 永久保存简单数据
  • 原文地址:https://www.cnblogs.com/Wu13241454771/p/14349180.html
Copyright © 2011-2022 走看看