greenlet
为了更好使用协程来完成多任务,python中greenlet模块对其封装,从而使得切换任务变得更加简单
安装方式

  1. pip3 install greenlet

示例代码:

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

gevent
greenlet已经实现了协程,但是这个工人切换,是不是觉得太麻烦了,不要着急,python还有一个比greenlet更强大的并且能够自动切换任务的模块`gevent`
其原理是当一个greentlet遇到IO(指的是input ouput输入输出,比如网络、文件操作等)操作时,比如访问网络,就自动切换到其他的greenlet,等到IO完成,再适当的时候切换回来继续执行。

由于IO操作非常耗时,经常使程序处于等待状态,有了gevent我们自动切换协程,就保证总有greenlet在运行,而不是等待IO

安装

  1. pip3 install gevent 

1.gevent的使用

  1. import gevent
  2.  
  3. def f(n):
  4. for i in range(n):
  5.   print(gevent.getcurrent(), i)
  6. g1 = gevent.spawn(f, 5)
  7. g2 = gevent.spawn(f, 5)
  8. g3 = gevent.spawn(f, 5)
  9. g1.join()
  10. g2.join()
  11. g3.join()

运行结果

  1. F:\python3.6\python.exe D:/pythonProjects/pynetwork/coroutine/gevent_demo.py
  2. <Greenlet "Greenlet-0" at 0x22ef10f5c48: f(5)> 0
  3. <Greenlet "Greenlet-0" at 0x22ef10f5c48: f(5)> 1
  4. <Greenlet "Greenlet-0" at 0x22ef10f5c48: f(5)> 2
  5. <Greenlet "Greenlet-0" at 0x22ef10f5c48: f(5)> 3
  6. <Greenlet "Greenlet-0" at 0x22ef10f5c48: f(5)> 4
  7. <Greenlet "Greenlet-1" at 0x22ef12dc048: f(5)> 0
  8. <Greenlet "Greenlet-1" at 0x22ef12dc048: f(5)> 1
  9. <Greenlet "Greenlet-1" at 0x22ef12dc048: f(5)> 2
  10. <Greenlet "Greenlet-1" at 0x22ef12dc048: f(5)> 3
  11. <Greenlet "Greenlet-1" at 0x22ef12dc048: f(5)> 4
  12. <Greenlet "Greenlet-2" at 0x22ef12dc148: f(5)> 0
  13. <Greenlet "Greenlet-2" at 0x22ef12dc148: f(5)> 1
  14. <Greenlet "Greenlet-2" at 0x22ef12dc148: f(5)> 2
  15. <Greenlet "Greenlet-2" at 0x22ef12dc148: f(5)> 3
  16. <Greenlet "Greenlet-2" at 0x22ef12dc148: f(5)> 4
  17.  
  18. Process finished with exit code 0

gevent切换执行

  1. import gevent
  2.  
  3. def f(n):
  4. for i in range(n):
  5.   print(gevent.getcurrent(), i)
  6.   # 用来模拟一个耗时操作,注意不是time模块中的sleep
  7.   gevent.sleep(1)
  8. g1 = gevent.spawn(f, 5)
  9. g2 = gevent.spawn(f, 5)
  10. g3 = gevent.spawn(f, 5)
  11. g1.join()
  12. g2.join()
  13. g3.join()

运行结果

  1. F:\python3.6\python.exe D:/pythonProjects/pynetwork/coroutine/gevent_demo.py
  2. <Greenlet "Greenlet-0" at 0x2c45e304c48: f(5)> 0
  3. <Greenlet "Greenlet-1" at 0x2c45e4cc048: f(5)> 0
  4. <Greenlet "Greenlet-2" at 0x2c45e4cc148: f(5)> 0
  5. <Greenlet "Greenlet-0" at 0x2c45e304c48: f(5)> 1
  6. <Greenlet "Greenlet-1" at 0x2c45e4cc048: f(5)> 1
  7. <Greenlet "Greenlet-2" at 0x2c45e4cc148: f(5)> 1
  8. <Greenlet "Greenlet-0" at 0x2c45e304c48: f(5)> 2
  9. <Greenlet "Greenlet-1" at 0x2c45e4cc048: f(5)> 2
  10. <Greenlet "Greenlet-2" at 0x2c45e4cc148: f(5)> 2
  11. <Greenlet "Greenlet-0" at 0x2c45e304c48: f(5)> 3
  12. <Greenlet "Greenlet-1" at 0x2c45e4cc048: f(5)> 3
  13. <Greenlet "Greenlet-2" at 0x2c45e4cc148: f(5)> 3
  14. <Greenlet "Greenlet-0" at 0x2c45e304c48: f(5)> 4
  15. <Greenlet "Greenlet-1" at 0x2c45e4cc048: f(5)> 4
  16. <Greenlet "Greenlet-2" at 0x2c45e4cc148: f(5)> 4
  17.  
  18. Process finished with exit code 0

3. 给程序打补丁

  1. from gevent import monkey
  2. import gevent
  3. import random
  4. import time
  5.  
  6. # 有耗时操作时需要
  7. monkey.patch_all() # 将程序中用到的耗时操作的代码,换为gevent中自己实现的模块
  8.  
  9. def coroutine_work(coroutine_name):
  10. for i in range(10):
  11. print(coroutine_name, i)
  12. time.sleep(random.random())
  13.  
  14. gevent.joinall([
  15. gevent.spawn(coroutine_work, "work1"),
  16. gevent.spawn(coroutine_work, "work2")
  17. ])

运行结果

  1. F:\python3.6\python.exe D:/pythonProjects/pynetwork/coroutine/gevent_test.py
  2. work1 0
  3. work2 0
  4. work2 1
  5. work1 1
  6. work1 2
  7. work1 3
  8. work2 2
  9. work1 4
  10. work1 5
  11. work2 3
  12. work1 6
  13. work1 7
  14. work2 4
  15. work2 5
  16. work1 8
  17. work1 9
  18. work2 6
  19. work2 7
  20. work2 8
  21. work2 9
  22.  
  23. Process finished with exit code 0

协程greenlet、gevent的更多相关文章

  1. python 协程 greenlet gevent

    一.并发的本质 切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长时间片到了 二.协程 ...

  2. 线程队列 concurrent 协程 greenlet gevent

    死锁问题 所谓死锁:是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进 ...

  3. day 34 线程队列 线程池 协程 Greenlet \Gevent 模块

    1 线程的其他方法 threading.current_thread().getName()    查询当前线程对象的名字 threading.current_thread().ident      ...

  4. 协程,greenlet原生协程库, gevent库

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

  5. 【python】-- 协程介绍及基本示例、协程遇到IO操作自动切换、协程(gevent)并发爬网页

    协程介绍及基本示例 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是协程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他 ...

  6. 并发编程(六)——进程/线程池、协程、gevent第三方库

    进程/线程池.协程.gevent第三方库 一.进程/线程池 1.进程池 (1)什么是进程池 如果需要创建的子进程数量不大,可以直接利用multiprocess中的Process来创建.但是当需要创建上 ...

  7. python 线程(其他方法,队列,线程池,协程 greenlet模块 gevent模块)

    1.线程的其他方法 from threading import Thread,current_thread import time import threading def f1(n): time.s ...

  8. 协程----greenlet模块,gevent模块

    1.协程初识,greenlet模块 2.gevent模块(需要pip安装) 一.协程初识,greenlet模块: 协程:是单线程下的并发,又称微线程,纤程.英文名Coroutine.一句话说明什么是线 ...

  9. 14 并发编程-(协程)-greenlet模块&gevent模块

    1.实现多个任务之间进行切换,yield.greenlet都没有实现检测I/O,greenlet在实现多任务切换下更简单 from greenlet import greenlet def eat(n ...

随机推荐

  1. centos安装系统全过程

    --查看系统 lsb_release -a --查看端口 netstat -lnp|grep 80 ps 进程ID #查看进程的详细信息 kill -9 进程ID --查看Java 版本 java - ...

  2. 解决Spring Boot OTS parsing error: Failed to convert WOFF 2.0

    <build> <resources> <resource> <directory>${project.basedir}/src/main/resour ...

  3. Exchange - Add Owner of Distribution Group

    User Interface: Open Exchange Management Console. Expand Microsoft Exchange On-Premises, then right ...

  4. PDF.js实现个性化PDF渲染(文本复制)

    我肥来啦

  5. SSH + Google Authenticator 安全加固

    1. SSH连接 Secure Shell(安全外壳协议,简称SSH)是一种加密的网络传输协议,可在不安全的网络中为网络服务提供安全的传输环境.SSH通过在网络中创建安全隧道来实现SSH客户端与服务器 ...

  6. Xshell设置密钥登录CentOS6.5_64位(文字命令版)

    1.新建/root/.ssh目录 mkdir /root/.ssh 2.创建authorized_keys文件 vi /root/.ssh/authorized_keys 3.复制公钥内容保存 :wq ...

  7. 【20180409】IT管理之IT十二条令

    团队越来越大,靠人管几乎有力无心,只能靠制度管理了. 前段时间对部门颁布了12条令,效果明显. 特此Mark. 汇报: 三条总结:汇报讲究精简,一个事情最多一句话概括. 一页报告:内容精简,报告一页w ...

  8. ThreadPoolExcutor 线程池 异常处理 (上篇)

    前言 最近看到crossoverJie的一篇文章:一个线程罢工的诡异事件 首先感谢原作者的分享,自己获益匪浅.然后是回想到自己的一次面试经历,面试官提问了线程池中的线程出现了异常该怎样捕获?会导致什么 ...

  9. Linux常用指令笔记

    目标:统计当前目录下java文件的个数 指令:`ls -R ./ | grep .java$ | wc -l` 原理:`ls -R ./`列出当前文件夹下的所有FILE,包括目录以及文件;`grep ...

  10. npm安装package.json中的模块依赖

    npm 一键安装 package.json里的依赖时有2种情况: 1.package.json不存在时 运行命令: npm init可自动创建package.json文件 2.package.json ...