@@ -28,6 +28,169 @@ yield表示协程在此暂停,并且将执行权交给其他协程。因为协
28
28
29
29
在这个例子中,我们将看到如何使用Asyncio的协程来模拟有限状态机。有限状态机(finite state machine or automaton, FSA)是一个数据血腥,不仅在工程领域应用广泛,在科学领域也很著名,例如数学和计算机科学等。我们要模拟的状态机如下图所示:
30
30
31
- .. images :: ../images/finite-state-machine.png
31
+ .. image :: ../images/finite-state-machine.png
32
32
33
- 在上图中,可以看到我们的系统有 **S1 **, **S2** **, **S3 **, **S4 ** 四个状态, **0 ** 和 **1 ** 是状态机可以从一个状态到另一个状态的值(这个过程叫做转换)。例如在本实验中,只有当只为1的时候, **S0 ** 可以转换到 **S1 ** ,当只为0的时候, **S0 ** 可以转换到 **S2 ** .Python代码如下,状态模拟从 **S0 ** 开始,叫做 **初始状态 ** ,最后到 **S4 ** ,叫做 **结束状态 ** 。
33
+ 在上图中,可以看到我们的系统有 **S1 **, **S2** **, **S3 **, **S4 ** 四个状态, **0 ** 和 **1 ** 是状态机可以从一个状态到另一个状态的值(这个过程叫做转换)。例如在本实验中,只有当只为1的时候, **S0 ** 可以转换到 **S1 ** ,当只为0的时候, **S0 ** 可以转换到 **S2 ** .Python代码如下,状态模拟从 **S0 ** 开始,叫做 **初始状态 ** ,最后到 **S4 ** ,叫做 **结束状态 ** 。 ::
34
+
35
+ # Asyncio Finite State Machine
36
+ import asyncio
37
+ import time
38
+ from random import randint
39
+
40
+
41
+ @asyncio.coroutine
42
+ def StartState():
43
+ print("Start State called \n")
44
+ input_value = randint(0, 1)
45
+ time.sleep(1)
46
+ if (input_value == 0):
47
+ result = yield from State2(input_value)
48
+ else:
49
+ result = yield from State1(input_value)
50
+ print("Resume of the Transition : \nStart State calling " + result)
51
+
52
+ @asyncio.coroutine
53
+ def State1(transition_value):
54
+ outputValue = str("State 1 with transition value = %s \n" % transition_value)
55
+ input_value = randint(0, 1)
56
+ time.sleep(1)
57
+ print("...Evaluating...")
58
+ if input_value == 0:
59
+ result = yield from State3(input_value)
60
+ else :
61
+ result = yield from State2(input_value)
62
+ result = "State 1 calling " + result
63
+ return outputValue + str(result)
64
+
65
+ @asyncio.coroutine
66
+ def State2(transition_value):
67
+ outputValue = str("State 2 with transition value = %s \n" % transition_value)
68
+ input_value = randint(0, 1)
69
+ time.sleep(1)
70
+ print("...Evaluating...")
71
+ if (input_value == 0):
72
+ result = yield from State1(input_value)
73
+ else :
74
+ result = yield from State3(input_value)
75
+ result = "State 2 calling " + result
76
+ return outputValue + str(result)
77
+
78
+ @asyncio.coroutine
79
+ def State3(transition_value):
80
+ outputValue = str("State 3 with transition value = %s \n" % transition_value)
81
+ input_value = randint(0, 1)
82
+ time.sleep(1)
83
+ print("...Evaluating...")
84
+ if (input_value == 0):
85
+ result = yield from State1(input_value)
86
+ else :
87
+ result = yield from EndState(input_value)
88
+ result = "State 3 calling " + result
89
+ return outputValue + str(result)
90
+
91
+ @asyncio.coroutine
92
+ def EndState(transition_value):
93
+ outputValue = str("End State with transition value = %s \n" % transition_value)
94
+ print("...Stop Computation...")
95
+ return outputValue
96
+
97
+ if __name__ == "__main__":
98
+ print("Finite State Machine simulation with Asyncio Coroutine")
99
+ loop = asyncio.get_event_loop()
100
+ loop.run_until_complete(StartState())
101
+
102
+ 运行代码,我们可以看到类似以下输出(译注,运行结果随机,这里给我译者运行的三次结果). ::
103
+
104
+ $ python3 coroutines.py
105
+ Finite State Machine simulation with Asyncio Coroutine
106
+ Start State called
107
+
108
+ ...Evaluating...
109
+ ...Evaluating...
110
+ ...Evaluating...
111
+ ...Evaluating...
112
+ ...Evaluating...
113
+ ...Evaluating...
114
+ ...Stop Computation...
115
+ Resume of the Transition :
116
+ Start State calling State 2 with transition value = 0
117
+ State 2 calling State 1 with transition value = 0
118
+ State 1 calling State 2 with transition value = 1
119
+ State 2 calling State 1 with transition value = 0
120
+ State 1 calling State 2 with transition value = 1
121
+ State 2 calling State 3 with transition value = 1
122
+ State 3 calling End State with transition value = 1
123
+
124
+ $ python3 coroutines.py
125
+ Finite State Machine simulation with Asyncio Coroutine
126
+ Start State called
127
+
128
+ ...Evaluating...
129
+ ...Evaluating...
130
+ ...Stop Computation...
131
+ Resume of the Transition :
132
+ Start State calling State 2 with transition value = 0
133
+ State 2 calling State 3 with transition value = 1
134
+ State 3 calling End State with transition value = 1
135
+
136
+ $ python3 coroutines.py
137
+ Finite State Machine simulation with Asyncio Coroutine
138
+ Start State called
139
+
140
+ ...Evaluating...
141
+ ...Evaluating...
142
+ ...Evaluating...
143
+ ...Evaluating...
144
+ ...Evaluating...
145
+ ...Evaluating...
146
+ ...Evaluating...
147
+ ...Stop Computation...
148
+ Resume of the Transition :
149
+ Start State calling State 1 with transition value = 1
150
+ State 1 calling State 2 with transition value = 1
151
+ State 2 calling State 1 with transition value = 0
152
+ State 1 calling State 3 with transition value = 0
153
+ State 3 calling State 1 with transition value = 0
154
+ State 1 calling State 2 with transition value = 1
155
+ State 2 calling State 3 with transition value = 1
156
+ State 3 calling End State with transition value = 1
157
+
158
+ |work |
159
+ ------
160
+
161
+ 每一个状态都由装饰器装饰: ::
162
+
163
+ @asyncio.coroutine
164
+
165
+ 例如, **S0 ** 的定义如下所示: ::
166
+
167
+ @asyncio.coroutine
168
+ def StartState():
169
+ print("Start State called \n")
170
+ input_value = randint(0, 1)
171
+ time.sleep(1)
172
+ if (input_value == 0):
173
+ result = yield from State2(input_value)
174
+ else:
175
+ result = yield from State1(input_value)
176
+ print("Resume of the Transition : \nStart State calling " + result)
177
+
178
+ 通过 ``random `` 模块的 ``randint(0, 1) `` 函数生成了 ``input_value `` 的值,决定了下一个转换状态。此函数随机生成1或0: ::
179
+
180
+ input_value = randint(0, 1)
181
+
182
+ 得到 ``input_value `` 的值之后,通过 ``yield from `` 命令调用下一个协程。 ::
183
+
184
+ if (input_value == 0):
185
+ result = yield from State2(input_value)
186
+ else:
187
+ result = yield from State1(input_value)
188
+
189
+ ``result `` 是下一个协程返回的string,这样我们在计算的最后就可以重新构造出计算过程。
190
+
191
+ 启动事件循环的代码如下: ::
192
+
193
+ if __name__ == "__main__":
194
+ print("Finite State Machine simulation with Asyncio Coroutine")
195
+ loop = asyncio.get_event_loop()
196
+ loop.run_until_complete(StartState())
0 commit comments