协程

协程,又称微线程,纤程。英文名Coroutine。顾名思义,协程是协作式的,也就是非抢占式的程序(线程是抢占式的)。协程的关键字是yield,一看到这个就想到了生成器对不对?那就顺便回顾一下生成器的知识点,只要叫什么器的,那肯定就是函数形式,生成器也是函数,只不过多了一个yield在函数中:

  1. def foo():
  2. print('ok')
  3. yield
  4.  
  5. foo()

猜一下foo()执行我的结果是什么?结果是什么都不会打印,为什么呢?打印foo()是什么看一下:

  1. # -*- coding: utf-8 -*-
  2.  
  3. def foo():
  4. print('ok')
  5. yield
  6.  
  7. gen = foo()
  8. print(gen)
  9.  
  10. >>><generator object foo at 0x000001AE31BCA318>

原来foo()是一个生成器函数,只能通过next放方法执行了。

  1. # -*- coding: utf-8 -*-
  2.  
  3. def foo():
  4. print('ok')
  5. yield
  6.  
  7. gen = foo()
  8. # print(gen)
  9. gen.__next__()
  10. >>>ok

这样才能打印出ok来。那除了__next__()方法,我们知道还有两种方法可以执行生成器函数:

  1. deffoo():print('ok')yieldprint('ok2')yield6#yield也可以返回内容,返回的内容给了调用他的那一步,相当于returngen=foo()next(gen)s=gen.__next__()print(s)#next()#只有两个yield,再执行这一步就会报错了>>>ok>>>ok2>>>6

next()

  1. deffoo():print('ok')s=yield6print(s)print('ok2')yieldgen=foo()print(next(gen))gen.send('创给yield的值')#send也可以执行一次生成器,还可以传值给yield>>>ok>>>6>>>创给yield的值>>>ok2

send()

简单的生产者消费者模型

为什么说yield是协程的关键字呢?因为协程是用户态的切换,就是说用户想什么时候切换就什么时候切换(这里的用户就是编程者),而yield刚好可以控制这一点。

协程的两个优点:

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

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

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

这里看不懂上面两个优点没关系,看下面的例子就能更好的理解了:

1.yield方式简单实现协程

这里将吃包子的人增加一个,看看yield怎么实现:

  1. import time
  2.  
  3. def customer(name):
  4. print('等包子。。。')
  5. while True:
  6. baozi = yield
  7. print('%s拿到了包子%s'%(name,baozi))
  8.  
  9. def producer(c1,c2):
  10. c1.__next__()
  11. c2.__next__()
  12. n = 0
  13. while True:
  14. time.sleep(1) #做包子需要一点时间
  15. c1.send(n)
  16. c2.send(n+1)
  17. n += 2
  18.  
  19. if __name__ == '__main__':
  20. c1 = customer('xiao')
  21. c2 = customer('bai')
  22. producer(c1,c2)

2.Greenlet方式

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

  1. from greenlet import greenlet
  2.  
  3. def test1():
  4. print(1111)
  5. gr2.switch()
  6. print(2222)
  7. gr2.switch()
  8.  
  9. def test2():
  10. print(3333)
  11. gr1.switch()
  12. print(4444)
  13.  
  14. gr1 = greenlet(test1)
  15. gr2 = greenlet(test2)
  16. gr1.switch()

没有安装这个库的话,需要安装一下,然后看打印的结果,是不是可以控制随时切换啦,很神奇。

  1. 1111
  2. 3333
  3. 2222
  4. 4444

3.Gevent方式

同样, 没有安装的话需要安装一下

  1. import gevent
  2. import requests,time
  3. start=time.time()
  4. def f(url):
  5. print('GET: %s' % url)
  6. resp =requests.get(url)
  7. data = resp.text
  8. print('%d bytes received from %s.' % (len(data), url))
  9.  
  10. # f('https://www.python.org/')
  11. # f('https://www.baidu.com/')
  12. # f('https://www.sina.com.cn/')
  13. # f("http://www.xiaohuar.com/hua/")
  14.  
  15. gevent.joinall([
  16. gevent.spawn(f, 'https://www.python.org/'),
  17. gevent.spawn(f, 'https://www.baidu.com/'),
  18. gevent.spawn(f, 'https://www.sina.com.cn/'),
  19. gevent.spawn(f, 'http://www.xiaohuar.com/hua/'),
  20. ])
  21.  
  22. print("cost time:",time.time()-start)

大家可以比较一下使用协程和直接按顺序执行有没有提升效率。

到了这里,协程的基础知识也说完了,还有很多专门开发关于协程的库,因为协程很有作用,这里的例子很简单,但是这里面门道很深的。进程和线程的内容,都是死的,但是协程可以灵活运用,需要不断的去研究创新的。

python进程和线程(六)的更多相关文章

  1. python 进程和线程(代码知识部分)

    二.代码知识部分 一 multiprocessing模块介绍: python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情 ...

  2. python 进程与线程(理论部分)

    一.理论部分 一 什么是进程 进程:正在进行的一个过程或者说一个任务.而负责执行任务则是cpu. 举例(单核+多道,实现多个进程的并发执行): egon在一个时间段内有很多任务要做:python备课的 ...

  3. python 进程和线程

    python中的进程.线程(threading.multiprocessing.Queue.subprocess) Python中的进程与线程 学习知识,我们不但要知其然,还是知其所以然.你做到了你就 ...

  4. Python进程、线程、协程

    进程和线程的解释 进程(process)和线程(thread)是操作系统的基本概念,计算机的核心是CPU,它承担了所有的计算任务: 单个CPU一次只能运行一个任务,代表单个CPU总是运行一个进程,其他 ...

  5. python进程、线程、协程(转载)

    python 线程与进程简介 进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资 ...

  6. Python进程和线程

    引入进程和线程的概念及区别 1.线程的基本概念 概念 线程是进程中执行运算的最小单位,是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但 ...

  7. Python进程、线程、协程详解

    进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源的管理和分配.任务的调度. ...

  8. python——进程、线程、协程

    Python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #!/usr/bin/env pytho ...

  9. Python进程与线程

    进程与线程:*进程: 进程是系统中程序执行和资源分配的基本单元, 每个进程都有自己的数据段(存储数据).代码段(存储代码).堆栈段(对象和变量). # 全局变量等资源在多个进程中不能          ...

随机推荐

  1. 关于python中phantomjs无法访问网页的处理

    笔者使用的系统是linux ubuntu,最近在学习爬虫的过程中遇到了一个抓狂的问题,我尝试使用selenium加phantomjs来登陆网页的时候,Pythony一直提示selenium无法找到元素 ...

  2. BZOJ_3996_[TJOI2015]线性代数_最大权闭合子图

    BZOJ_3996_[TJOI2015]线性代数_最大权闭合子图 Description 给出一个N*N的矩阵B和一个1*N的矩阵C.求出一个1*N的01矩阵A.使得 D=(A*B-C)*A^T最大. ...

  3. BZOJ_3307_雨天的尾巴_线段树合并+树上差分

    BZOJ_3307_雨天的尾巴_线段树合并 Description N个点,形成一个树状结构.有M次发放,每次选择两个点x,y 对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成 所有发放后 ...

  4. 拿Proxy可以做哪些有意思的事儿

    Proxy是什么 首先,我们要清楚,Proxy是什么意思,这个单词翻译过来,就是 代理.可以理解为,有一个很火的明星,开通了一个微博账号,这个账号非常活跃,回复粉丝.到处点赞之类的,但可能并不是真的由 ...

  5. Mtcnn进行人脸剪裁和对齐

    from scipy import misc import tensorflow as tf import detect_face import cv2 import matplotlib.pyplo ...

  6. PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 使用Poi实现android中根据模板文件生成Word文档的功能.这里的模板文件是doc文件.如果模板文件是docx文件的话,请阅读 ...

  7. 安卓开发笔记(二十六):Splash实现首页快速开屏功能

    我们在进行安卓开发的时候,首页开有两种方式,一种是利用handler将一个活动进行延时,时间到达之后软件则会跳转到第二个活动当中.而另一种方法则是更加常用的方法,利用splash实现首页的快速开屏,这 ...

  8. 深入理解OkHttp源码(一)——提交请求

    本篇文章主要介绍OkHttp执行同步和异步请求的大体流程.主要流程如下图: 主要分析到getResponseWidthInterceptorChain方法,该方法为具体的根据请求获取响应部分,留着后面 ...

  9. 【.NETCore开源】开弓没有回头箭

    2019.2.11 开工大吉!经过了半个月的休假,今天回归岗位重新拾起工作,却发现熟悉的代码生疏了.年前的计划回忆不起来了,俗称"节后综合症". 忆半月圈子 过年放假的前几天有多篇 ...

  10. 【php性能优化】关于写入文件操作的取舍方案

    对于使用php对文件进行写入操作有两种方案一种使用 file_put_contents() 和 fopen()/fwrite()/fclose() 两种方案至于应该怎么选,我觉得应该分情况选择,下面是 ...