1、实现多个任务之间进行切换,yield、greenlet都没有实现检测I/O,greenlet在实现多任务切换下更简单

  1. from greenlet import greenlet
  2. def eat(name):
  3. print(f"{name} eat 1")
  4. g2.switch('egon') # 切换
  5. print(f"{name} eat 2")
  6. g2.switch()
  7. def play(name):
  8. print(f"{name} play 1")
  9. g1.switch()
  10. print(f"{name} play 2")
  11. g1 = greenlet(eat)
  12. g2 = greenlet(play)
  13. g1.switch('egon') # 程序从此处执行
  14.  
  15. egon eat 1
  16. egon play 1
  17. egon eat 2
  18. egon play 2

2、一个协程遇到IO操作自动切换到其它协程(如何实现检测IO,yield、greenlet都无法实现,就用到了gevent模块(select机制))

2.1 gevent模块

可以轻松的实现并发或异步编程,在gevent中用到的主要模式是Greenlet,

2.1.1、遇到io阻塞时会自动切换任务 --只实现识别gevent可以识别的阻塞

  1. # 遇到io阻塞会自动切换任务
  2. import gevent,time
  3. def eat(name):
  4. print(f"{name} eat1")
  5. gevent.sleep(2) # 模拟io阻塞
  6. print(f"{name} eat2")
  7. def play(name):
  8. print(f"{name} play1")
  9. gevent.sleep(2)
  10. print(f"{name} play2")
  11. start = time.time()
  12. g1 = gevent.spawn(eat,'alex')
  13. g2 = gevent.spawn(play,'alex')
  14. g1.join()
  15. g2.join()
  16. stop = time.time()
  17. print(stop-start)
  18.  
  19. alex eat1
  20. alex play1
  21. alex eat2
  22. alex play2
  23. 2.007000207901001

2.1.2、实际情况中的应用gevent  打补丁(monkey.patch_all()) 识别 所有阻塞

alex eat1
alex play1
alex eat2
alex play2
2.005999803543091

3、基于gvent模块实现并发的套接字通信

服务端:

  1. # 基于 gevent
  2. from gevent import monkey;monkey.patch_all()
  3. import socket
  4. import gevent
  5.  
  6. def Server(ip_port):
  7. server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  8. server.bind(ip_port)
  9. server.listen(5)
  10. while True:
  11. conn,addr = server.accept()
  12. gevent.spawn(communicate,conn)
  13. server.close()
  14. def communicate(conn):
  15. while True:
  16. try:
  17. data = conn.recv(1024).decode('utf-8')
  18. conn.send(data.upper().encode('utf-8'))
  19. except Exception as e:
  20. print(e)
  21. break
  22. conn.close()
  23. if __name__ == '__main__':
  24. ip_port = ('127.0.0.1',8080)
  25. Server(ip_port)
  26. # g = gevent.spawn(Server,ip_port)
  27. # g.join()

客户端:启动500个线程模拟500个客户端向服务端发消息

  1. import socket
  2. from threading import Thread,currentThread
  3. def client():
  4. client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  5. ip_port = ('127.0.0.1',8080)
  6. client.connect(ip_port)
  7. while True:
  8. client.send(f"{currentThread().getName()} hello".encode('utf-8'))
  9. data = client.recv(1024)
  10. print(data.decode('utf-8'))
  11. client.close()
  12. if __name__ == '__main__':
  13. for i in range(500):
  14. t = Thread(target=client)
  15. t.start()

14 并发编程-(协程)-greenlet模块&gevent模块的更多相关文章

  1. 并发编程协程(Coroutine)之Gevent

    并发编程协程之Gevent Gevent官网文档地址:http://www.gevent.org/contents.html 基本概念 我们通常所说的协程Coroutine其实是corporate r ...

  2. 并发编程~~~协程~~~greenlet模块, gevent模块

    一 协程 1. 协程: 单线程下的并发,又称微线程,纤程.协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的. 并发真正的核心: 切换并且保持状态. 开启协程并发的执行,自己的程序把控着C ...

  3. python 并发编程 协程 greenlet模块

    一 greenlet模块 不敢是yield,还是greenlet都没有实现检测io,实现遇到io切换效果 如果我们在单个线程内有20个任务,要想实现在多个任务之间切换,使用yield生成器的方式过于麻 ...

  4. Python并发编程协程(Coroutine)之Gevent

    Gevent官网文档地址:http://www.gevent.org/contents.html 基本概念 我们通常所说的协程Coroutine其实是corporate routine的缩写,直接翻译 ...

  5. python 并发编程 协程 目录

    python 并发编程 协程 协程介绍 python 并发编程 协程 greenlet模块 python 并发编程 协程 gevent模块 python 并发编程 基于gevent模块实现并发的套接字 ...

  6. 并发编程 - 协程 - 1.协程概念/2.greenlet模块/3.gevent模块/4.gevent实现并发的套接字通信

    1.协程并发:切+保存状态单线程下实现并发:协程 切+ 保存状态 yield 遇到io切,提高效率 遇到计算切,并没有提高效率 检测单线程下 IO行为 io阻塞 切 相当于骗操作系统 一直处于计算协程 ...

  7. 网络编程基础--协程--greenlet切换---gevent自动识别 IO ---

    协程: 1 单线程来实现并发---协程: 协程:是单线程下的并发,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程, 即协程是由用户程序自己控制调度的 只 ...

  8. python语法基础-并发编程-协程-长期维护

    ###############    协程    ############## # 协程 # 小知识点, # 协程和进程和线程一样都是实现并发的手段, # 开启一个线程,创建一个线程,还是需要开销, ...

  9. python 并发编程 协程池

    协程池 from gevent.pool import Pool from gevent import monkey;monkey.patch_all() import gevent from gev ...

随机推荐

  1. 解决IE6中img标签 图片透明

    <!--[if IE 6]> <script type="text/javascript"> function correctPNG() { for (va ...

  2. JS object(对象)的学习汇总

    Object(对象)是在所有的编程语言中都十分重要的一个概念,对于事物我们可以把他们看作是一个对象,而每一个事物都有自己的表示的属性和对于某一信息作出的相应的操作.而这些东西就变成了事物的属性和方法. ...

  3. web service与EJB的区别

    1.WebService可以说是跨平台的,因为它采用的是XML技术,说穿了就是把你的请求按照该WebServece的标准将参数传过去,然后服务器返回结果,当然了最重要的是参数的传递和结果的返回都是采用 ...

  4. Thunder7.2.13.3884 JayXon

    更新日志: 更新迅雷7. 更新VipService 2.7 更新SQLite 更新zlib 不再精简msvcr71.dll.msvcp71.dll 不再精简64位BHO 破解了本地离线重命名30个字符 ...

  5. angular的中文文档在这里。。

    链接 仿ant-design的  angular组件 echarts文档

  6. 二、深度解析HTML5之视频播放和音频播放

    一:视频播放 传统的视频音频播放是通过flash插件的形式完成,不是所有的浏览器都安装了flash插件,而且手机端不支持flash,这就导致视频和音频的播放会有很大的麻烦. 于是,HTML5增加音频和 ...

  7. java IO 学习(二)

    文件表示形式的转换: 一.从系统文件变成java中可以使用的文件对象 File file = new FIle("文件的路径"); 二.读取文件系统中文件的原始字节流,要读取字符流 ...

  8. spring-security-4 (5)spring security Java配置实现自定义表单认证与授权

    前面三篇讲解了spring security的搭建以及简单的表单认证与授权原理.本篇将实现我们自定义的表单登录与认证.  本篇不会再讲项目的搭建过程,因为跟第二节的搭建如出一辙.本篇也不会将项目中所有 ...

  9. win7 安装redis服务

    Redis官方是不支持windows的,只是 Microsoft Open Tech group 在 GitHub上开发了一个Win64的版本,项目地址是: https://github.com/MS ...

  10. 3——FFMPEG之解复用器-----AVInputFormat(转)

    1. 数据结构: AVInputFormat为FFMPEG的解复用器对象,通过调用av_register_all(),FFMPEG所有的解复用器保存在以first_iformat为链表头的链表中,且还 ...