ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

01-gevent完成多任务

2021-12-12 23:02:11  阅读:199  来源: 互联网

标签:spawn 01 join img gevent sleep 执行 多任务


gevent完成多任务

一、原理

gevent实现多任务并不是依靠多进程或是线程,执行的时候只有一个线程,在遇到堵塞的时候去寻找可以执行的代码。本质上是一种协程。

二、代码实现

import gevent


def f1(n):
    for i in range(n):
        print(gevent.getcurrent(), i)
        gevent.sleep(0.5)


def f2(n):
    for i in range(n):
        print(gevent.getcurrent(), i)
        gevent.sleep(0.5)


def f3(n):
    for i in range(n):
        print(gevent.getcurrent(), i)
        gevent.sleep(0.5)

# 创建gevent对象,spawn()函数中的第二个参数是前面需要执行的函数中需要传入的参数
# 此时仅仅是创建对象并没有执行
g1 = gevent.spawn(f1, 5)
g2 = gevent.spawn(f1, 5)
g3 = gevent.spawn(f1, 5)

# 调用join()函数的时候才开始执行
g1.join()
g2.join()
g3.join()

解读:

程序从上往下执行,在执行到g1.join()的时候,会去执行对应的函数,这个函数在执行的过程中会出现堵塞现象。在这个时候程序并不会一直在那里等待,而是回去继续寻找其他的gevent创建的对象,继续执行代码。在这个程序里面,会继续执行g2.join(),依此类推,后面代码的执行情况和这个一样。(这点就像是异步I/O)

注意:

  • gevent.spawn()---------->用于创建gevent对象,并没有执行函数
  • g1.join()---------->此时才开始执行对应的函数
  • 在gevent()中要想有sleep()造成的堵塞,必须使用gevent.sleep()。(前提是没有打补丁)

三、gevent打补丁

# 打补丁,导入这个模块,并执行指定的函数,那么遇到需要耗时的操作都会将其替换成gevent()中的耗时操作
from gevent import monkey
monkey.patch_all()

 打完补丁之后可以使用time.sleep()

def f1(n):
    for i in range(n):
        print(gevent.getcurrent(), i)
        time.sleep(0.5)

如上面代码所示,将完整代码中的gevent.sleep()全部替换为time.sleep()效果不会发生改变

四、更简单的输出方式

观察上面的程序,我们发现在调用gevent创建的对象的时候,代码过于冗长。加入创建了一百个gevent对象,那岂不是要写一百个join()函数。

为了解决这个问题,gevent给我们提供了一个joinall()函数。

 语法如下:

gevent.joinall([
    gevent.spawn(functionname1),
    gevent.spawn(functionname2),
    gevent.spawn(functionname3)
])

 

对上面咱们已经写好的代码进行如下修改,修改完成之后代码执行效果不变。

gevent.joinall([
    gevent.spawn(f1, 5),
    gevent.spawn(f2, 5),
    gevent.spawn(f3, 5)
])

 

 五、gevent实现图片下载器

import gevent
import urllib.request
from gevent import monkey

monkey.patch_all()

def img_download(img_name, img_url):
    req = urllib.request.urlopen(img_url)    # 获取的是响应状态
    content = req.read()
    with open(img_name, "wb") as f:
        f.write(content)


def main():
    gevent.joinall([
        gevent.spawn(img_download, "1.jpg", "http://n.sinaimg.cn/photo/transform/700/w1000h500/20211002/3c9c-4fecc919c8af637a9f6cc7c82b4cf3bc.jpg"),
        gevent.spawn(img_download, "2.jpg" , "https://n.sinaimg.cn/photo/400/w200h200/20210416/a6a4-knvsnuf5950596.jpg")
    ])



if __name__ == "__main__":
    main()

 

标签:spawn,01,join,img,gevent,sleep,执行,多任务
来源: https://www.cnblogs.com/xhlqss/p/15680990.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有