文章目录

回忆进程与线程 引入

我们之前说,有比较耗时的操作得交给线程来干,因为进程是同步调用,阻塞执行,串行执行的,那么我们就要用线程,异步调用,非阻塞,并行执行,这样的话才能提升效率。

问题来了,假设线程中也有几个子任务,耗时,然后我们程序都是串行的,也就一个Thread里面的run()都是串行执行的,一个子任务,比方下载很慢,其他任务都阻塞在那,就效率又很低了。

这时的线程就好像以前的进程一样尴尬。

我们python就出来一个微线程,可以并行操作的,线程的子任务部分,也称为

携程

协程(Coroutine) cor - routine 也可以看出并行的含义

比如,我们有很多任务要做,打游戏,学习python,配朋友,这就是三个进程。在打游戏中,我有 黑暗之魂1,2,3,上古卷轴5,也就是4个线程,当然,上古卷轴5有100个mod,我需要更新100个mod,就有了100个协程。因为更新比较耗时,必须并行调用 更新mod的任务。

greenlet

python封装了库greenlet来实现协程,我们来看个例子:#-*- utf-8 -*-

from time import sleep,time

from greenlet import greenlet

def taskA():

for i in range(5):

print('A' str(i))

gB.switch()

sleep(1) # 模拟网络阻塞 耗时操作

def taskB():

for i in range(5):

print('B' str(i))

gC.switch()

sleep(1) # 模拟网络阻塞 耗时操作

def taskC():

for i in range(5):

print('C' str(i))

gA.switch()

sleep(1) # 模拟网络阻塞 耗时操作

if __name__ == "__main__":

t1 = time()

gA = greenlet(run = taskA)

gB = greenlet(run = taskB)

gC = greenlet(run = taskC)

gA.switch()

t2 = time()

print("time consume",t2-t1)

类似process thread, greenlet也必须传target参数(他命名为run参数 反正一个意思)

这里主要是实现A B C并行轮询,但是我们可以看到这样写很蠢,需要人工切换,而且效率也不算高,于是官方的greenlet不好用,就有大佬弄出来gevent库(第三方),在greenlet基础上再封装一波,可以实现自动切换。

gevent

利用spawn函数传要做的事(taskA B C),spawn有 产卵; 引发; 引起 这几个意思,有点run的含义。

注意,我们之前在进程里面遇到过,主进程启动完子进程start以后就跑路了,导致子进程也gg,这样我们就用join阻塞,让主进程别溜,这里也是同样的道理。#-*- utf-8 -*-

from time import sleep,time

from gevent import monkey,spawn

def taskA():

for i in range(3):

print('A' str(i))

sleep(1) # 模拟网络阻塞 耗时操作

def taskB():

for i in range(3):

print('B' str(i))

sleep(1) # 模拟网络阻塞 耗时操作

def taskC():

for i in range(3):

print('C' str(i))

sleep(1) # 模拟网络阻塞 耗时操作

if __name__ == "__main__":

t1 = time()

gA = spawn(run = taskA)

gB = spawn(run = taskB)

gC = spawn(run = taskC)

gA.join()

gB.join()

gC.join()

t2 = time()

print("time consume",t2-t1)

结果:A0

A1

A2

B0

B1

B2

C0

C1

C2

time consume 9.041131258010864

我们发现,

1: 并没有轮询ABC ABC 这样的啊

2: 并没有并行啊2333 其实上面的greenlet也没有实现并行??? 还是9s

monkey

我们的time不适合这个场合的,于是利用monkey.patch_all()#-*- utf-8 -*-

import time

from gevent import monkey,spawn

monkey.patch_all()

def taskA():

for i in range(3):

print('A' str(i))

time.sleep(1) # 模拟网络阻塞 耗时操作

def taskB():

for i in range(3):

print('B' str(i))

time.sleep(1) # 模拟网络阻塞 耗时操作

def taskC():

for i in range(3):

print('C' str(i))

time.sleep(1) # 模拟网络阻塞 耗时操作

if __name__ == "__main__":

t1 = time.time()

gA = spawn(run = taskA)

gB = spawn(run = taskB)

gC = spawn(run = taskC)

gA.join()

gB.join()

gC.join()

t2 = time.time()

print("time consume",t2-t1)

这里 必须time.sleep才能生效 因为monkey在背后偷偷重载替换了原生的sleep,你直接from time import sleep, monkey匹配不到

结果:A0

B0

C0

A1

B1

C1

A2

B2

C2

time consume 3.036893606185913

Process finished with exit code 0

可见,比较完美实现了并行,time consume 时间消耗 从9s 并行变成了 3s

总结

我们直接用gevent monkey就行了 其他的执行方式太麻烦了,简直就是再造轮子:)

上古卷轴5python_python 基础(五)协程 —— 微线程 greenlet gevent相关推荐

  1. 学习笔记(35):Python网络编程并发编程-协程(yield,greenlet,gevent模块)

    立即学习:https://edu.csdn.net/course/play/24458/296457?utm_source=blogtoedu 协程(yield,greenlet,gevent) 1. ...

  2. 协程和线程的区别、协程原理与优缺点分析、在Java中使用协程

    文章目录 什么是协程 协程的优点与缺点 协程实现原理. 协程与线程在不同编程语言的实现 在Java中使用协程 Kilim介绍 Kilim整合Java,使用举例 小总结 什么是协程 相对于协程,你可能对 ...

  3. python协程和线程区别_python 协程 及其与python多线程的区别和联系

    协程(coroutine)又称微线程,纤程,是种用户级别的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时候,将寄存器上下文和栈保存到其他地方,等待切换回来的时候恢复,并从之前保存的寄存器 ...

  4. Go 面试官:什么是协程,协程和线程的区别和联系?

    大家好,我是煎鱼. 最近金三银四,是面试的季节.在我的 Go 读者交流群里出现了许多小伙伴在讨论自己面试过程中所遇到的一些 Go 面试题. 今天的男主角,是工程师的必修技能,那就是 "什么是 ...

  5. 什么是协程,协程和线程的区别和联系?

    1 进程 进程是什么 进程是操作系统对一个正在运行的程序的一种抽象,进程是资源分配的最小单位. 进程在操作系统中的抽象表现 为什么有进程 为什么会有 "进程" 呢?说白了还是为了合 ...

  6. 协程 vs 线程 demo

    2019独角兽企业重金招聘Python工程师标准>>> 协程 vs 线程 demo 博客分类: java package my; import java.util.concurren ...

  7. Kotlin学习笔记26 协程part6 协程与线程的关系 Dispatchers.Unconfined 协程调试 协程上下文切换 Job详解 父子协程的关系

    参考链接 示例来自bilibili Kotlin语言深入解析 张龙老师的视频 1 协程与线程的关系 import kotlinx.coroutines.* import java.util.concu ...

  8. Kotlin学习笔记22 协程part2 join CoroutineScope 协程vs线程

    参考链接 示例来自bilibili Kotlin语言深入解析 张龙老师的视频 1 Job的join方法 import kotlinx.coroutines.* /*** Job的join方法* 它会挂 ...

  9. 以爬虫为例,单线程,协程,线程,进程之间性能的比较,原来协程可以这么快?

    前言 因为刚刚学习到了协程,然后之前也对爬虫有一定的了解,所以打算结合之前学的线程和进程,和协程进行对比,看看它的性能到底有多高,在测试完成后,结果还是不错的!下面就直接上代码了,因为代码逻辑都比较简 ...

  10. 协程相比线程到底好在哪里?

    协程虽然被提出的时间很早,但是使用它的年限很短.尤其是最近几年,随着 Go.Lua 等语言的流行,把协程推向了一个新的高潮. 在所有语言中都存在着层级调用,比如 A 调用 B,B 在执行过程中又调用了 ...

最新文章

  1. Java BIO、NIO、AIO
  2. 计算机算法设计与分析二--分治
  3. 史上最全程序员调查报告:一半开发者是全栈,七成认为自己能力高于平均水平
  4. java mvc 分页查询条件_java分页条件查询-GridManager.js表格插件+Pageable分页对象+mybatis pagehelper分页插件...
  5. 启明云端分享| 盘点 ESP32-S3到底有哪些功能特性
  6. 光纤交换机光纤通道协议介绍
  7. 怎么wps解除合并单元格_wps表格怎么锁定单元格
  8. Python maximum recursion depth exceeded while calling a Python object (gevent的SSL无限递归错误)的问题解决
  9. linux下的磁盘空间使用
  10. KDD2018 阿里巴巴论文揭示自家大规模视觉搜索算法
  11. 笨办法学 Linux 中文版 翻译完成
  12. python3.X出现关于模块(i18n)的不能使用的解决方法
  13. WEB标准学习路程之CSS:7.表格,滚动条,打印
  14. word 远程过程调用失败。 (异常来自 HRESULT:0x800706BE) 解决方法
  15. Octotree:一款超实用的GitHub可视化代码树插件
  16. SCI论文撰写和投稿过程的详细介绍 - 易智编译EaseEditing
  17. Servlet的Request和Response
  18. 阿里云服务器如何购买?三种方式可买(图文教程举例)
  19. 犯错误很正常,可怕的是同样的错误重复在犯!
  20. CRNN文本识别模型

热门文章

  1. java严格模式_es严格模式、对象和扩展。
  2. python小爬虫,爬取文章(知乎专栏)片段
  3. 网页iframe访问
  4. 你应该知道的Redis事务
  5. 设计模式学习之外观模式
  6. java 编程思想 一 第二章(对象)
  7. java源码-LinkedHashMap
  8. 浅谈我的UI设计之路
  9. React源码分析 - 组件初次渲染
  10. Exchange企业实战技巧(25)将日历发布到Internet