經過生成器yield實現單線程的狀況下實現併發運算效果(異步IO的雛形)

1、協程:
一、生成器只有在調用時纔會生成相應的數據
二、調用方式有 " str__next__.()   str.send() ",
三、而且每調用一次就產生一個值調用到最後一個值後會報錯
四、報錯可用try和except作異常處理
 
注意:
next:是直接調用yield,並不會傳值。
send:是調用並直接傳值給yield。

 

 1 #!/usr/bin/env python
 2 # -*- coding:utf8 -*-
 3 # Author:Dong Ye
 4 
 5 
 6 '''
 7 定義兩個模型:
 8 一個是生產包子的。(生成器)
 9 另外一個是吃包子的。(迭代器)
10 
11 這段功能實現了異步IO的雛形,也是一個簡單的協程處理方式。
12 協程的特色:實際是串行方式分開執行的,但因爲運行效果快,給人的感受像是並行。
13 所以,協程也叫做:單線程下的並行執行效果。
14 協程是包含在線程裏的一個單位,線程時進程的一個單位。
15 例如:enginx在異步單線程下,比多線程要快好多倍,也就是這種效果。
16 '''
17 
18 import time
19 
20 
21 #吃包子的
22 def consumer(name):
23     print('%s 準備吃包子了!' % name)
24     while True:
25         baozi = yield
26         print("包子[%s]來了。被[%s]吃了!" %(baozi,name))
27 
28 
29 #生產包子的
30 def producer(name):
31     #先定義2個協程(消費者)#將函數變成生成器
32     c1 = consumer('A')   #2個消費者
33     c2 = consumer('B')   #至關於2個協程(進程,線程,協程)
34     #開始調用生成器初始化(準備吃包子)
35     c1.__next__()     #開始調用生成器,只有next的時候纔會到yield進行下一個操做
36     c2.__next__()
37     print('老子開始吃包子拉!')
38     #循環的次數,每次循環都會傳值給生成器(產生什麼樣的包子)
39     for i in range(10):
40         time.sleep(1)
41         print("作了一個包子,分2半,一人一半")
42         c1.send(i) #包子的類型
43         c2.send(i)
44 
45 
46 producer("alex")
47 
48 
49 
50 '''
51 #手動作包子:
52 c = consumer("dy")
53 c.__next__()
54 #c.__next__()
55 
56 b1 = "韭菜餡"
57 c.send(b1)     #調用+傳值
58 #c.__next__()  #只調用,不傳值
59 '''
60 
61 
62 
63 
64 顯示結果:
65 A 準備吃包子了!
66 B 準備吃包子了!
67 老子開始吃包子拉!
68 作了一個包子,分2半,一人一半  #任務1
69 包子[0]來了。被[A]吃了!      #任務2
70 包子[0]來了。被[B]吃了!      #任務3
71 作了一個包子,分2半,一人一半
72 包子[1]來了。被[A]吃了!
73 包子[1]來了。被[B]吃了!
74 作了一個包子,分2半,一人一半
75 包子[2]來了。被[A]吃了!
76 包子[2]來了。被[B]吃了!
77 作了一個包子,分2半,一人一半
78 包子[3]來了。被[A]吃了!
79 包子[3]來了。被[B]吃了!
80 作了一個包子,分2半,一人一半
81 包子[4]來了。被[A]吃了!
82 包子[4]來了。被[B]吃了!
83 作了一個包子,分2半,一人一半
84 包子[5]來了。被[A]吃了!
85 包子[5]來了。被[B]吃了!
86 作了一個包子,分2半,一人一半
87 包子[6]來了。被[A]吃了!
88 包子[6]來了。被[B]吃了!
89 作了一個包子,分2半,一人一半
90 包子[7]來了。被[A]吃了!
91 包子[7]來了。被[B]吃了!
92 作了一個包子,分2半,一人一半
93 包子[8]來了。被[A]吃了!
94 包子[8]來了。被[B]吃了!
95 作了一個包子,分2半,一人一半
96 包子[9]來了。被[A]吃了!
97 包子[9]來了。被[B]吃了!
協程的示例
相關文章
相關標籤/搜索