zoukankan      html  css  js  c++  java
  • 多任务——协程

    迭代器

    可迭代对象:实现迭代器协议的对象,迭代器协议:对象实现了_iter()_和_next()_方法

    在python中,可以通过isinstance()判断一个对象是否可以迭代

    from collections import Iterable
    
    # 判断列表
    print(isinstance([], Iterable))
    
    # 判断元组
    print(isinstance((), Iterable))
    
    # 判断字典
    print(isinstance({}, Iterable))
    
    # 判断字符串
    print(isinstance("", Iterable))
    
    # 判断整数
    print(isinstance(100, Iterable))
    
    # 判断boolean
    print(isinstance(False, Iterable))

    生成器

    包含yield关键字的函数,也是一个迭代器,调用next()方法,yield:保持当前程序的执行状态

    • yield关键字有两点作用:
      • 保存当前运行状态(断点),然后暂停执行,即将生成器(函数)挂起
      • 将yield关键字后面表达式的值作为返回值返回,此时可以理解为起到了return的作用
    • 可以使用next()函数让生成器从断点处继续执行,即唤醒生成器(函数)
    • 也可以使用send()函数来唤醒生成器,使用send()可以在唤醒的同事向断点出传入一个附加数据数据

    协程

    协程,又称微线程,单线程下的并发,是一种用户态的轻量级线程,由用户之间控制调度的

    协程的本质就是在单线程下,由用户之间控制一个任务遇到IO阻塞了就切换另外一个任务去执行,以此来提升效率

    在python中使用协程完成多任务,用greenlet模块对其封装,从而使得切换任务变的更加简单

    安装方式:

    sudo pip3 install greenlet
    import greenlet
    import time
    def wotk():
        while True:
            print("---A---")
            g2.switch()
            time.sleep(1)
    
    
    def work():
        while True:
            print("---B---")
            g1.switch()
            time.sleep(2)
    
    
    if __name__ == '__main__':
        # 生成greelent对象
        g1=greenlet.greenlet(run=wotk)
        g2=greenlet.greenlet(run=work)
    
        g1.switch()
        g2.switch()

    gevent

    greenlet已经实现了协程,但是这个还的人工切换,是不是觉得太麻烦了,不要捉急,python还有一个比greenlet更强大的并且能够自动切换任务的模块gevent

    安装:

    pip3 install gevent

    代码如下:

    import gevent
    import time
    from gevent import monkey  # 打补丁
    
    def task(index):
        for i in range(3):
            print('任务%d----代码快%d,当前gevent对象名称:%s'%(index,i,str(gevent.getcurrent())))
            time.sleep(1)
    
    
    if __name__ == '__main__':
        # 打补丁
        monkey.patch_all()
        gevent.joinall([gevent.spawn(task,1),
                        gevent.spawn(task, 2),
                        gevent.spawn(task, 3)])
        print("主线程执行的最后代码")

    打印结果如下:

    协程之并发下载器实现案例

    import urllib.request
    from gevent import monkey
    import gevent
    import time
    
    # 网络数据下载实现
    def download(url,file_name):
        # url:要下载数据的网站
        # file_name:存储在本地的文件名
        response=urllib.request.urlopen(url)
    
        # 保存文件
        write_file=open("文件路径"+file_name,"wb")
    
        while True:
            content=response.read(4096)
            if content:
                write_file.write(content)
            else:
                break
        write_file.close()
    
    if __name__ == '__main__':
        # 打补丁
        monkey.patch_all()
        start_time=time.time()
        url1="https://desk-fd.zol-img.com.cn/t_s960x600c5/g5/M00/02/00/ChMkJ1bKw0yIXFW5AAbUq3ToEXAAALG0wMHWJsABtTD684.jpg"
        url2="https://desk-fd.zol-img.com.cn/t_s960x600c5/g5/M00/0F/08/ChMkJlauzGuIDo5-AAmEKbHNhzwAAH89wIKvi8ACYRB721.jpg"
        url3="https://desk-fd.zol-img.com.cn/t_s960x600c5/g5/M00/05/0C/ChMkJ1l_JQ6IXG6dAAiAKWFIRycAAfSaADwC8oACIBB894.jpg"
        gevent.joinall([gevent.spawn(download,url1,"1.jpg"),
                        gevent.spawn(download, url2, "2.jpg"),
                        gevent.spawn(download, url3, "3.jpg")])
        end_time=time.time()
        print("下载的时间为:{}".format(end_time-start_time))

    打印结果如下:

  • 相关阅读:
    solr不是标准的java project解决方案
    solr 索引库的维护
    solr linux配置
    JSON跨域问题总结
    阿里云字体图标的引用
    Android 体系结构
    java.lang.NoClassDefFoundError 异常
    java java.uitl.Random产生随机数
    Android 应用间的集成
    iOS7状态栏字体颜色修改
  • 原文地址:https://www.cnblogs.com/xiaolu915/p/10517386.html
Copyright © 2011-2022 走看看