Skip to content

Commit f773fb3

Browse files
committed
整理文件
1 parent e3a03b6 commit f773fb3

471 files changed

Lines changed: 11231 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Fluent-Python/.ipynb_checkpoints/16. Coroutines-checkpoint.ipynb

Lines changed: 4126 additions & 0 deletions
Large diffs are not rendered by default.

Fluent-Python/.ipynb_checkpoints/17. Concurrency with Futures-checkpoint.ipynb

Lines changed: 456 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {
6+
"toc": true
7+
},
8+
"source": [
9+
"<h1>Table of Contents<span class=\"tocSkip\"></span></h1>\n",
10+
"<div class=\"toc\"><ul class=\"toc-item\"><li><span><a href=\"#Thread-Versus-Coroutine:-A-Comparison\" data-toc-modified-id=\"Thread-Versus-Coroutine:-A-Comparison-1\"><span class=\"toc-item-num\">1&nbsp;&nbsp;</span>Thread Versus Coroutine: A Comparison</a></span></li></ul></div>"
11+
]
12+
},
13+
{
14+
"cell_type": "markdown",
15+
"metadata": {},
16+
"source": [
17+
"##### Thread Versus Coroutine: A Comparison"
18+
]
19+
},
20+
{
21+
"cell_type": "markdown",
22+
"metadata": {},
23+
"source": [
24+
"spinner with thread"
25+
]
26+
},
27+
{
28+
"cell_type": "code",
29+
"execution_count": 4,
30+
"metadata": {
31+
"ExecuteTime": {
32+
"end_time": "2019-07-29T07:19:32.178708Z",
33+
"start_time": "2019-07-29T07:19:32.171043Z"
34+
}
35+
},
36+
"outputs": [],
37+
"source": [
38+
"import threading\n",
39+
"import itertools\n",
40+
"import time\n",
41+
"import sys\n",
42+
"\n",
43+
"\n",
44+
"class Signal: #1 Signal类有一个可变成员 go, 用它来控制线程的开启或者关闭.\n",
45+
" go = True\n",
46+
"\n",
47+
"\n",
48+
"def spin(msg, signal): #2 第二个参数是 Signal的实例\n",
49+
" write, flush = sys.stdout.write, sys.stdout.flush\n",
50+
" for char in itertools.cycle('|/-\\\\'): #3 这是一个无限循环, 参考 itertools.cycle\n",
51+
" status = char + '' + msg\n",
52+
" write(status)\n",
53+
" flush()\n",
54+
" write('\\x08' * len(status)) #4 The trick to do text-mode animation: move the cursor back with backspace characters (\\x08).\n",
55+
" #然而在jupyter里面看不到......\n",
56+
" time.sleep(.1)\n",
57+
" if not signal.go: #5 If the go attribute is no longer True, exit the loop.\n",
58+
" break\n",
59+
" write(' ' * len(status) + '\\x08' * len(status)) #6 Clear the status line by overwriting with spaces and \n",
60+
" # moving the cursor back to the beginning.\n",
61+
"\n",
62+
"\n",
63+
"def slow_function(): #7 模拟一个耗时的计算\n",
64+
" time.sleep(3) #8 sleep函数阻塞主线程, 同时使主线程释放GIL, 此时副线程得以运行.\n",
65+
" return '高科技'\n",
66+
"\n",
67+
"\n",
68+
"def supervisor(): #9 开辟副线程, 运行副线程并且模拟耗时计算, 最后杀死线程\n",
69+
" signal = Signal()\n",
70+
" # 开一个线程\n",
71+
" spinner = threading.Thread(target=spin, args=('thinking', signal))\n",
72+
" print('spinner object:', spinner) #10\n",
73+
" spinner.start() #11\n",
74+
" result = slow_function() #12\n",
75+
" signal.go = False #13\n",
76+
" spinner.join() #14\n",
77+
" return result\n",
78+
"\n",
79+
"\n",
80+
"def main():\n",
81+
" result = supervisor() #15\n",
82+
" print('Answer:', result)"
83+
]
84+
},
85+
{
86+
"cell_type": "code",
87+
"execution_count": 5,
88+
"metadata": {
89+
"ExecuteTime": {
90+
"end_time": "2019-07-29T07:19:35.705475Z",
91+
"start_time": "2019-07-29T07:19:32.683967Z"
92+
}
93+
},
94+
"outputs": [
95+
{
96+
"name": "stdout",
97+
"output_type": "stream",
98+
"text": [
99+
"spinner object: <Thread(Thread-5, initial)>\n",
100+
"|thinkin/thinkin-thinkin\\thinkin|thinkin/thinkin-thinkin\\thinkin|thinkin/thinkin-thinkin\\thinkin|thinkin/thinkin-thinkin\\thinkin|thinkin/thinkin-thinkin\\thinkin|thinkin/thinkin-thinkin\\thinkin|thinkin/thinkin-thinkin\\thinkin|thinkin Answer: 高科技\n"
101+
]
102+
}
103+
],
104+
"source": [
105+
"main()"
106+
]
107+
},
108+
{
109+
"cell_type": "markdown",
110+
"metadata": {},
111+
"source": [
112+
"spinner with asyncio"
113+
]
114+
},
115+
{
116+
"cell_type": "code",
117+
"execution_count": 7,
118+
"metadata": {
119+
"ExecuteTime": {
120+
"end_time": "2019-07-29T08:08:52.735740Z",
121+
"start_time": "2019-07-29T08:08:52.727606Z"
122+
}
123+
},
124+
"outputs": [],
125+
"source": [
126+
"import asyncio\n",
127+
"import itertools\n",
128+
"import sys\n",
129+
"\n",
130+
"\n",
131+
"@asyncio.coroutine #1\n",
132+
"def spin(msg): #2\n",
133+
" write, flush = sys.stdout.write, sys.stdout.flush\n",
134+
" for char in itertools.cycle('|/-\\\\'):\n",
135+
" status = char + ' ' + msg\n",
136+
" write(status)\n",
137+
" flush()\n",
138+
" write('\\x08' * len(status))\n",
139+
" try:\n",
140+
" yield from asyncio.sleep(.1) #3\n",
141+
" except asyncio.CancelledError: #4\n",
142+
" break\n",
143+
" write(' ' * len(status) + '\\x08' * len(status))\n",
144+
"\n",
145+
"\n",
146+
"@asyncio.coroutine\n",
147+
"def slow_function(): #5\n",
148+
" yield from asyncio.sleep(3) #6\n",
149+
" return '高科技'\n",
150+
"\n",
151+
"\n",
152+
"@asyncio.coroutine\n",
153+
"def supervisor(): #7\n",
154+
" spinner = asyncio.async(spin('thinking')) #8\n",
155+
" print('spinner object:', spinner) #9\n",
156+
" result = yield from slow_function() #10\n",
157+
" spinner.cancel() #11\n",
158+
" return result\n",
159+
"\n",
160+
"\n",
161+
"def main():\n",
162+
" loop = asyncio.get_event_loop() #12\n",
163+
" result = loop.run_until_complete(supervisor()) #13\n",
164+
" loop.close()\n",
165+
" print('Answer:', result)"
166+
]
167+
},
168+
{
169+
"cell_type": "markdown",
170+
"metadata": {},
171+
"source": [
172+
"<center>总结</center>\n",
173+
"\n",
174+
"1. 如果你想使用 asyncio 来实现协程, 最好加上 @asyncio.coroutine 装饰器.\n",
175+
"2. 这里不需要外界提供一个信号来控制协程.\n",
176+
"3. 使用 asyncio 来实现协程时, IO-bound的操作要小心, 为了不阻塞事件循环, 需要用 yield from asyncio.sleep(.1).\n",
177+
"4. 如果抛出 asyncio.CancelledError 异常, 就退出循环, 协程中止.\n",
178+
"5. slow_function 现在也是一个协程(因为他原本有IO-bound的操作).\n",
179+
"6. The yield from asyncio.sleep(3) expression handles the control flow to the main loop, \n",
180+
"which will resume this coroutine after the sleep delay.\n",
181+
"7. supervisor 现在也是一个协程函数, 内部会 通过 yield from 调用协程函数 slow_function.\n",
182+
"8. asyncio.async(…) schedules the spin coroutine to run, wrapping it in a ***Task*** object, which is ***returned immediately***.\n",
183+
"9. 打印 Task 对象.\n",
184+
"10. yield from slow_function(), 并获得其返回值. 同时 时间循环将会继续运行, 这是因为 slow_fucntion 内部 yield from 了 asyncio.sleep(3), 控制权会立刻回到主循环.\n",
185+
"11. 通过调用 Task 对象的 cancell 方法, raise asyncio.CancelledError, 抛出异常的地方是Task包装的协程函数**当前挂起的 yield 语句的位置**. 协程函数可以捕获异常, 延迟异常甚至拒绝异常.\n",
186+
"12. 获得事件循环的***引用***.\n",
187+
"13. 启动 supervisor 协程函数直到他终止并且获取其返回值."
188+
]
189+
},
190+
{
191+
"cell_type": "code",
192+
"execution_count": null,
193+
"metadata": {},
194+
"outputs": [],
195+
"source": []
196+
}
197+
],
198+
"metadata": {
199+
"kernelspec": {
200+
"display_name": "Python 3",
201+
"language": "python",
202+
"name": "python3"
203+
},
204+
"language_info": {
205+
"codemirror_mode": {
206+
"name": "ipython",
207+
"version": 3
208+
},
209+
"file_extension": ".py",
210+
"mimetype": "text/x-python",
211+
"name": "python",
212+
"nbconvert_exporter": "python",
213+
"pygments_lexer": "ipython3",
214+
"version": "3.6.7"
215+
},
216+
"toc": {
217+
"base_numbering": 1,
218+
"nav_menu": {},
219+
"number_sections": true,
220+
"sideBar": true,
221+
"skip_h1_title": true,
222+
"title_cell": "Table of Contents",
223+
"title_sidebar": "Contents",
224+
"toc_cell": true,
225+
"toc_position": {},
226+
"toc_section_display": true,
227+
"toc_window_display": false
228+
}
229+
},
230+
"nbformat": 4,
231+
"nbformat_minor": 2
232+
}

0 commit comments

Comments
 (0)