一、协程

协程,又叫微线程,纤程。英文名Coroutine。协程本质上就是一个线程

优点1:协程极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越来越明显。(简单来说没有切换的消耗)

优点2:不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好,所以执行效率比多线程高很多。(没有锁的概念)

因为协程是一个线程执行,那怎么利用多核CPU呢?最简单的方法是多进程+协程,既充分利用多核,又充分发挥协程的高效率,可获得极高的性能。

二、yield的简单实现

  1. #_*_ coding:utf-8 _*_
  2. # Author:Simon
  3. # Datetime:2019/9/2 21:07
  4. # Software:PyCharm
  5.  
  6. import time
  7. import queue
  8.  
  9. def consumer(name):
  10. print("--->ready to eat baozi...")
  11. while True:
  12. new_baozi = yield
  13. print("[%s] is eating baozi %s" % (name,new_baozi))
  14. #time.sleep(1)
  15.  
  16. def producer():
  17.  
  18. r = con.__next__()
  19. r = con2.__next__()
  20. n = 0
  21. while 1:
  22. time.sleep(1)
  23. print("\033[32;1m[producer]\033[0m is making baozi %s and %s" %(n,n+1) )
  24. con.send(n)
  25. con2.send(n+1)
  26.  
  27. n +=2
  28.  
  29. if __name__ == '__main__':
  30. con = consumer("c1")
  31. con2 = consumer("c2")
  32. p = producer()

三、Greenlet模块

greenlet是一个用C实现的协程模块,相比与python自带的yield,它可以使你在任意函数之间随意切换,而不需把这个函数先声明为generator

  1. #_*_ coding:utf-8 _*_
  2. # Author:Simon
  3. # Datetime:2019/9/2 21:29
  4. # Software:PyCharm
  5. from greenlet import greenlet
  6.  
  7. def test1():
  8. print(12)
  9. gr2.switch()
  10. print(34)
  11. gr2.switch()
  12. def test2():
  13. print(56)
  14. gr1.switch()
  15. print(78)
  16.  
  17. gr1 = greenlet(test1)
  18. gr2 = greenlet(test2)
  19. gr1.switch()

四、Gevent模块

本质就是封装了greenlet模块,它能检测I/O并且遇到I/O自动切换到另外一个任务执行;可以帮我们提升效率

  1. #_*_ coding:utf-8 _*_
  2. # Author:Simon
  3. # Datetime:2019/9/2 21:39
  4. # Software:PyCharm
  5.  
  6. import gevent
  7.  
  8. import requests,time
  9.  
  10. start=time.time()
  11.  
  12. def f(url):
  13. print('GET: %s' % url)
  14. resp =requests.get(url)
  15. data = resp.text
  16. print('%d bytes received from %s.' % (len(data), url))
  17.  
  18. gevent.joinall([
  19.  
  20. gevent.spawn(f, 'https://www.jd.org/'),
  21. gevent.spawn(f, 'https://www.xiaohua.com/'),
  22. gevent.spawn(f, 'https://www.baidu.com/'),
  23. gevent.spawn(f, 'https://www.taobao.com/'),
  24.  
  25. ])
  26.  
  27. # f('https://www.jd.org/')
  28. # f('https://www.xiaohua.com/')
  29. # f('https://baidu.com/')
  30. # f('https://www.taobao.com/')
  31. #
  32. # print("cost time:",time.time()-start)

gevent异步提交任务

  1. from gevent import monkey;monkey.patch_all()
  2. import gevent
  3. import time
  4.  
  5. def eat(name):
  6. print('%s eat 1' % name)
  7. time.sleep(3)
  8. print('%s eat 2' % name)
  9.  
  10. def play(name):
  11. print('%s play 1' % name)
  12. time.sleep(4)
  13. print('%s play 2' % name)
  14.  
  15. g1=gevent.spawn(eat,'simon')
  16. g2=gevent.spawn(play,'zhuzhu')
  17.  
  18. # time.sleep(5)
  19.  
  20. # g1.join()
  21. # g2.join()
  22.  
  23. gevent.joinall([g1,g2]) #相当于上边两行代码
  24.  
  25. 打印:
  26. simon eat 1
  27. zhuzhu play 1
  28. simon eat 2
  29. zhuzhu play 2

基于gevent模块实现并发的套接字通信

单线程、多任务的I/O操作。

  1. #基于gevent实现
  2. from gevent import monkey,spawn;monkey.patch_all()
  3. from socket import *
  4.  
  5. def communicate(conn):
  6. while True:
  7. try:
  8. data=conn.recv(1024)
  9. if not data:break
  10. conn.send(data.upper())
  11. except ConnectionResetError:
  12. break
  13. conn.close()
  14.  
  15. def server(ip,port):
  16. server = socket(AF_INET, SOCK_STREAM)
  17. server.bind((ip,port))
  18. server.listen(5)
  19.  
  20. while True:
  21. conn, addr = server.accept()
  22. spawn(communicate,conn) #造一个协程对象,提交完这个对象它不会执行
  23. server.close()
  24.  
  25. if __name__ == '__main__':
  26. g=spawn(server,'127.0.0.1',8090)
  27. g.join()
  1. ##客户端
  2.  
  3. from socket import *
  4. from threading import Thread,currentThread
  5.  
  6. def client():
  7. client=socket(AF_INET,SOCK_STREAM)
  8. client.connect(('127.0.0.1',8090))
  9.  
  10. while True:
  11. client.send(('%s hello' %currentThread().getName()).encode('utf-8'))
  12. data=client.recv(1024)
  13. print(data.decode('utf-8'))
  14. client.close()
  15. if __name__ == '__main__':
  16. for i in range(500):
  17. t=Thread(target=client)
  18. t.start()

Python之路【第十七篇】:Python并发编程|协程的更多相关文章

  1. python 并发编程 协程 目录

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

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

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

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

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

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

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

  5. Python之并发编程-协程

    目录 一.介绍 二. yield.greenlet.gevent介绍 1.yield 2.greenlet 3.gevent 一.介绍 协程:是单线程下的并发,又称微线程,纤程.英文名Coroutin ...

  6. python并发编程&协程

    0x01 前导 如何基于单线程来实现并发? 即只用一个主线程(可利用的cpu只有一个)情况下实现并发: 并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操 ...

  7. python 并发编程 协程 gevent模块

    一 gevent模块 gevent应用场景: 单线程下,多个任务,io密集型程序 安装 pip3 install gevent Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步 ...

  8. python 并发编程 协程 协程介绍

    协程:是单线程下的并发,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的 需要强调的是: 1. python的线程属于内 ...

  9. 【python之路36】进程、线程、协程相关

    线程详细用法请参考:http://www.cnblogs.com/sunshuhai/articles/6618894.html 一.初始多线程 通过下面两个例子的运行效率,可以得知多线程的速度比单线 ...

随机推荐

  1. 使用 Python 和 Flask 设计 RESTful API

    近些年来 REST (REpresentational State Transfer) 已经变成了 web services 和 web APIs 的标配. 在本文中我将向你展示如何简单地使用 Pyt ...

  2. java的static和this

    1>static:静态修饰符   static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念.    被sta ...

  3. C/C++的内存对齐

    1.内存对齐之pragma pack语法 语法:#pragma pack( [show] | [push | pop] [, identifier], n )作用:指定结构,联合和类的包对齐方式(pa ...

  4. docker时区问题

    解决: dockerfile: RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime#update application timezoneR ...

  5. HDFS部署测试记录(2019/05)

    目录 HDFS部署测试记录 0.HDFS基础知识 1.基本组成结构与文件访问过程 2.NameNode启动时如何维护元数据 3.HDFS文件上传流程 1.系统环境 1.安装大致记录: 2.磁盘分区 3 ...

  6. Java学习-056-Jsoup爬虫获取中国所有的三级行政区划数据(一)

    在涉及地址服务时,经常需要用到地址信息的获取,而行政区划可能不定期的发生变化,所以我们需要获取最新的行政区划信息.因行政区划数据量较大,Java中可以使用Jsoup进行数据的获取.处理. 大家经常用到 ...

  7. awk:for循环输出文件名

    简单来说,有file1.txt, file2.txt, file3.txt file1.txt如下: 1 a 4 d d g file2.txt如下: 2 b g 6 9 0 file3.txt如下: ...

  8. kafka中的配额管理(限速)机制

    kafka支持配额管理,从而可以对Producer和Consumer的produce&fetch操作进行流量限制,防止个别业务压爆服务器.本文主要介绍如何使用kafka的配额管理功能. 1 K ...

  9. 仿简书MarkDown编辑器可同步滚动

    模仿简书的MarkDown编辑器,使用Angular8写的示例 1.支持同步滚动 编辑的过程中,右侧预览界面会同步滚动.滚动右侧预览界面,左侧编辑区也会同步滚动哦 2.支持语法高亮 如下: using ...

  10. 使用powercli创建模板与克隆虚机

    用powercli练练手,需从实际案例出发,本节将使用powercli写两个demo,一个是创建模板,并根据模板创建新的虚机:另一个demo是克隆虚机. [注意] 1.创建模板与克隆操作只能在vcen ...