首页 > 代码库 > #协程介绍及基本示例

#协程介绍及基本示例

 

 

技术分享
  1 #协程介绍及基本示例
  2 
  3 #Gevent协程(单线程,串行)在线程里启动
  4 ‘‘‘
  5 协程,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程:
  6         协程是一种用户态的轻量级线程。
  7 
  8 协程拥有自己的寄存器上下文和栈。协程调度切换时,
  9         将寄存器上下文和栈保存到其他地方,在切回来的时候,
 10         恢复先前保存的寄存器上下文和栈。因此:
 11 
 12 协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),
 13         每次过程重入时,就相当于进入上一次调用的状态,换种说法:
 14         进入上一次离开时所处逻辑流的位置。
 15 
 16 协程的好处:
 17 
 18 1无需线程上下文切换的开销
 19 
 20 2无需原子操作锁定及同步的开销
 21   "原子操作(atomic operation)是不需要synchronized",
 22     所谓原子操作是指不会被线程调度机制打断的操作;
 23     这种操作一旦开始,就一直运行到结束,
 24     中间不会有任何 context switch (切换到另一个线程)。
 25     原子操作可以是一个步骤,也可以是多个操作步骤,
 26     但是其顺序是不可以被打乱,或者切割掉只执行部分。
 27     视作整体是原子性的核心。
 28     
 29 3方便切换控制流,简化编程模型
 30 
 31 4高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题。
 32     所以很适合用于高并发处理。
 33  
 34 
 35 缺点:
 36 
 37 1无法利用多核资源:协程的本质是个单线程,它不能同时将 单个CPU 的多个核用上,
 38         协程需要和进程配合才能运行在多CPU上.
 39         当然我们日常所编写的绝大部分应用都没有这个必要,
 40         除非是cpu密集型应用。
 41         
 42 2进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序
 43 
 44 
 45 ‘‘‘
 46 ‘‘‘
 47 #使用yield实现协程操作例子
 48 
 49 import time
 50 import queue
 51 def consumer(name):
 52     print("--->starting eating baozi...")
 53     while True:
 54         new_baozi = yield  #返回,唤醒接收数据
 55         print("[%s] is eating baozi %s" % (name,new_baozi))
 56         #time.sleep(1)
 57  
 58 def producer():
 59  
 60     r = con.__next__()
 61     r = con2.__next__()
 62     n = 0
 63     while n < 5:
 64         n +=1
 65         con.send(n)#send 的作用唤醒传递数据yield
 66         con2.send(n)
 67         print("1m[producer] is making baozi %s" %n )
 68  
 69  
 70 if __name__ == ‘__main__‘:
 71     con = consumer("c1")
 72     con2 = consumer("c2")
 73     p = producer()
 74 
 75 ‘‘‘
 76 ‘‘‘
 77 #举例
 78 import time
 79 def home():
 80     print(‘in func 1‘)
 81     time.sleep(5)
 82     print(‘home exec done‘)
 83 
 84 def bbs():
 85     print(‘in func 2‘)
 86     time.sleep(2)
 87 ‘‘‘
 88 
 89 #greenlet 已经封装好的协程
 90 #io操作就切换
 91 
 92 ‘‘‘
 93 greenlet是一个用C实现的协程模块,
 94     相比与python自带的yield,它可以使你在任意函数之间随意切换,
 95     而不需把这个函数先声明为generator
 96 
 97 ‘‘‘
 98 ‘‘‘
 99 # -*- coding:utf-8 -*-
100 from greenlet import greenlet
101  
102  
103 def test1():
104     print(12)
105     gr2.switch()
106     print(34)
107     gr2.switch()
108  
109  
110 def test2():
111     print(56)
112     gr1.switch()
113     print(78)
114  
115  
116 gr1 = greenlet(test1)#启动一个协程
117 gr2 = greenlet(test2)
118 gr1.switch()
119 ‘‘‘
120 
121 
122 #Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,
123 #    在gevent中用到的主要模式是Greenlet,
124 #    它是以C扩展模块形式接入Python的轻量级协程。
125 #    Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。
126 
127 
128 import gevent
129  
130 def func1():
131     print(\033[31;1m李闯在跟海涛搞...\033[0m)
132     gevent.sleep(2)
133     print(\033[31;1m李闯又回去跟继续跟海涛搞...\033[0m)
134  
135 def func2():
136     print(\033[32;1m李闯切换到了跟海龙搞...\033[0m)
137     gevent.sleep(1)
138     print(\033[32;1m李闯搞完了海涛,回来继续跟海龙搞...\033[0m)
139  
140  
141 gevent.joinall([
142     gevent.spawn(func1),
143     gevent.spawn(func2),
144     #gevent.spawn(func3),
145 ])
#协程介绍及基本示例

 

#协程介绍及基本示例