• Python学习日记-第三十八天-生成器(第二节)


    系列文章目录

    • 使用greenlet,gevent完成多任务

    一、使用greenlet,gevent完成多任务

    这里要先在pycharm里面提前安装好greenlet和gevent的包

     

     

     

    操作: 

     代码:

    1. from greenlet import greenlet
    2. import time
    3. def test1():
    4. while True:
    5. print("--a--")
    6. gr2.switch()
    7. time.sleep(0.5)
    8. def test2():
    9. while True:
    10. print("--b--")
    11. gr1.switch()
    12. time.sleep(0.5)
    13. gr1 = greenlet(test1)
    14. gr2 = greenlet(test2)
    15. # 切换gr1中运行
    16. gr1.switch()

    运行结果:

    这里的greenlet比yield实现起来还要更简单一点 

    下面是使用的gevent,这个是用的比较多的一种,功能更强大

    其原理是当一个greenlet遇到io(指的是input output 输入输出时,比如网络,文件操作等),比如访问网络,就自动切换到其他的greenlet,等到io操作完成,再在适当的时候切换回来继续执行。由于io操作相当耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待io

    操作:

     

    这里通过spawn创建一个对象,其实就是greenlet,第一个参数是指定将来要执行任务的名字,第二个参数如果有的话就可以传递,没有的话可以不写

    输出结果:

     如果要验证这个是否是多任务的话,使用gevent.sleep就可以

     输出结果:

    最后控制台输出的时候,是一次输出三个结果的


    案例:做一个图片下载器

    现在浏览器找一个图片

    举例:在网上找一个图片

     鼠标右键单击,下面有一个审查元素,再点击一下这个小箭头,后面鼠标停在哪一个图片上,右边的小窗口就会跟上

     我这里选择的是这个老虎,把箭头指向的这一串网址复制下来,右键选择copy,copy element。复制好了,单独粘贴到一个文件里,在选择这一串网址

     

    操作:

     

     最后点开查看就行:

    同样也是可以爬视频的

    上面只是简单的爬一张照片,接下来就是用gevent同时爬多张图片

     

    下面是同时下载两个的操作:

     代码:

    1. import urllib.request
    2. import gevent
    3. from gevent import monkey
    4. monkey.patch_all()
    5. def down_loader(image_name, img_url):
    6. req = urllib.request.urlopen(img_url)
    7. img_contend = req.read()
    8. with open(image_name, "wb") as f:
    9. f.write(img_contend)
    10. def main():
    11. gevent.joinall([
    12. gevent.spawn(down_loader, "2.jpg", "https://p0.ssl.qhimgs1.com/sdr/400__/t01a3829bbb034da41e.jpg"),
    13. gevent.spawn(down_loader, "3.jpg", "https://p0.ssl.qhimgs1.com/sdr/400__/t01a55368c03c6ba28a.jpg")
    14. ])
    15. if __name__ == "__main__":
    16. main()

     

     要下载更过的话,望joinall里面扔网址就行了


    总结

    最后总结一下进程,线程,协程对比

    1. 进程是资源分配的单位
    2. 线程是操作系统调度的单位
    3. 进程切换需要的资源很大,效率很低
    4. 线程切换需要的资源一般,效率一般(当前在不考虑GIL的情况下,后续会说的)
    5. 协程切换任务资源很小,效率高
    6. 多进程,多线程根据cup核数不一样,可能是并行的,但是协程是在一个线程中,所以是并发的
  • 相关阅读:
    C++:delete和delete[]释放内存的区别
    JVM:执行引擎
    【java进阶06:数组】使用一维数组模拟栈数据结构 使用二维数组模拟酒店,酒店管理系统 Arrays工具类 冒泡排序算法、选择排序算法、二分法
    STM32-串口通信波特率计算以及寄存器的配置详解
    每日一库:Prometheus
    洛谷 中位数
    35岁危机来临前,程序员如何未雨绸缪?
    随笔---Unity RSA加密 后端解密失败,XML格式与PEM格式
    JUNIT使用和注意、以及断言的介绍使用、SpringBoot Test测试类的使用、maven配置使用junit详细介绍
    递归查询实现
  • 原文地址:https://blog.csdn.net/arizia/article/details/128175706