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()

01-gevent完成多任务的更多相关文章

  1. Python 使用gevent实现多任务

    import gevent import time # 如果需要默认的 time.sleep(0.5) 需要打补丁 from gevent import monkey monkey.patch_all ...

  2. 多任务5-协程(IO密集型适用)--gevent完成多任务及monkey补丁

    代码: import gevent def f1(n): for i in range(n): print(gevent.getcurrent(),i) gevent.sleep(1) def f2( ...

  3. Python多任务之协程

    前言 协程的核心点在于协程的使用,即只需要了解怎么使用协程即可:但如果你想了解协程是怎么实现的,就需要了解依次了解可迭代,迭代器,生成器了: 如果你只想看协程的使用,那么只需要看第一部分内容就行了:如 ...

  4. python多任务的实现:线程,进程,协程

    什么叫“多任务”呢?简单地说,就是操作系统可以同时运行多个任务.打个比方,你一边在用浏览器上网,一边在听MP3,一边在用Word赶作业,这就是多任务,至少同时有3个任务正在运行.还有很多任务悄悄地在后 ...

  5. python多任务——协程的使用

    使用yield完成多任务 import time def test1(): while True: print("--1--") time.sleep(0.5) yield Non ...

  6. python就业班-淘宝-目录.txt

    卷 TOSHIBA EXT 的文件夹 PATH 列表卷序列号为 AE86-8E8DF:.│ python就业班-淘宝-目录.txt│ ├─01 网络编程│ ├─01-基本概念│ │ 01-网络通信概述 ...

  7. python高级编程之 web静态服务器

    返回固定数据 import socket def request_handler(new_client_socket): """ 响应客户端请求的核心函数 "& ...

  8. 多任务-python实现-gevent(2.1.15)

    @ 目录 1.说明 2.代码 关于作者 1.说明 上个博文携程实现的多任务 依然是一个进程,一个线程,只不过执行了不同的代码部分 这里使用gevent,或者greenlet 当gevent执行的时候遇 ...

  9. 戴文的Linux内核专题:01介绍

    转自Linux中国 译者按:本文作者戴文.科利尔.约翰逊(Devyn Collier Johnson)今年才19岁,但是他在Linux内核.人工智能.编程语言方面拥有丰富的经验,本文是其在linux. ...

随机推荐

  1. 容器安全产品Aqua调研

    前言 近年来,随着云计算的发展,企业数字化的进程不断加快,业务纷纷开始上云,云原生的概念最近两年也是十分火热,在新业务场景下也随之产生了新的安全问题,如k8s安全.devsecops.微服务安全.Se ...

  2. CG Kit探索移动端高性能渲染

    内容来源:华为开发者大会2021 HMS Core 6 Graphics技术论坛,主题演讲<CG Kit探索移动端高性能渲染> 演讲嘉宾:华为海思麒麟GPU团队工程师 大家好,我来自华为海 ...

  3. Github树型插件--Octotree

    octotree 是一款chrome插件,用于将 GitHub 项目代码以树形格式展示,而且在展示的列表中,我们可以下载指定的文件,而不需要下载整个项目. 官网地址:https://www.octot ...

  4. 一些需要记住的linux命令

    1. 系统帮助命令                      ----man 2. 数据同步写入磁盘               ----sync 3. 查找文件命令                  ...

  5. 「后端小伙伴来学前端了」Vuex进阶操作,让你的代码更加高效(简称如何学会偷懒 【手动狗头】)

    学妹手机里的美照 前言 前一篇写了Vuex基本使用,用起来还稍稍有些繁琐,代码有很多 冗余的地方,这篇就带着大家用更简单的方式来使用Vuex(其实就是怎么更好的偷懒,用更少的代码来完之前的事情) 进入 ...

  6. npm 配置 registry 以及使用 nrm

    由于众所周知的原因,我们的内网链接互联网时非常不稳定,速度慢而且经常下载失败.为了提高下载安装 npm 包的体验,很多人都会把 npm 的 registry 配置成国内镜像,我们一般用的比较多的就是淘 ...

  7. 打开order by的大门,一探究竟《死磕MySQL系列 十二》

    在日常开发工作中,你一定会经常遇到要根据指定字段进行排序的需求. 这时,你的SQL语句类似这样. select id,phone,code from evt_sms where phone like  ...

  8. linux安全性增加

    账户安全问题 Linux  默认会安装很多不必要的用户和用户组,如果不需要某些用户或者组,就要立即删除它,因为账户越多,系统就越不安全,很可能被黑客利用,进而威胁到服务器的安全. Linux系统中可以 ...

  9. Django向数据库批量插入数据

    # 如何向数据库一次性插入多条数据 # 方法一:效率极低,不推荐使用 for i in range(1000): models.Book.objects.create(title=f'第{i}本书') ...

  10. 01 eclipse搭建maven的web工程(3.1)

    eclipse搭建maven的web工程(3.1) 一.下载并在eclipse安装JDK环境[查看] 二.下载并在eclipse安装maven环境[查看] 三.新建maven-webapp工程: 1. ...