并发是指一次处理多件事。 并行是指一次做多件事。 二者不同,但是有联系。 一个关于结构,一个关于执行。 并发用于制定方案,用来解决可能(但未必)并行的问题。
使用线程实现文本式旋转指针
代码语言:javascript复制# -*- coding: utf-8 -*-
# @Time : 2021/3/4 下午9:38
# @Author : zhongxin
# @Email : 490336534@qq.com
# @File : spinner_thread.py
import threading
import itertools
import time
import sys
class Signal:
go = True
def spin(msg, signal):
write, flush = sys.stdout.write, sys.stdout.flush
for char in itertools.cycle('|/-\'):
status = char ' ' msg
write(status)
flush()
write('x08' * len(status))
time.sleep(.1)
if not signal.go:
break
write(' ' * len(status) 'x08' * len(status))
def slow_function():
time.sleep(3)
return 42
def supervisor():
signal = Signal()
spinner = threading.Thread(target=spin, args=('thinking!', signal))
print('spinner object:', spinner)
spinner.start()
result = slow_function()
signal.go = False
spinner.join()
return result
def main():
result = supervisor()
print('Answer:', result)
if __name__ == '__main__':
main()
文本式旋转指针
使用协程实现文本旋转指针
代码语言:javascript复制# -*- coding: utf-8 -*-
# @Time : 2021/3/4 下午9:51
# @Author : zhongxin
# @Email : 490336534@qq.com
# @File : spinner_asyncio.py
import asyncio
import itertools
import sys
class Signal:
go = True
@asyncio.coroutine
def spin(msg):
write, flush = sys.stdout.write, sys.stdout.flush
for char in itertools.cycle('|/-\'):
status = char ' ' msg
write(status)
flush()
write('x08' * len(status))
try:
yield from asyncio.sleep(.1)
except asyncio.CancelledError:
break
write(' ' * len(status) 'x08' * len(status))
@asyncio.coroutine
def slow_function():
yield from asyncio.sleep(3)
return 42
@asyncio.coroutine
def supervisor():
spinner = asyncio.create_task(spin('thinking!'))
print('spinner object:', spinner)
result = yield from slow_function()
spinner.cancel()
return result
def main():
loop = asyncio.get_event_loop()
result = loop.run_until_complete(supervisor())
loop.close()
print('Answer:', result)
if __name__ == '__main__':
main()
⚠️协程的优势:协程是可以暂停和恢复的函数
回调地狱
代码语言:javascript复制如果一个操作需要依赖之前操作的结果,那就得嵌套回调。
def stage1(res1):
res2 = step1(res1)
api2(res2, stage2)
def stage2(res2):
res3 = step2(res2)
api3(res3, stage3)
def stage3(res3):
step3(res3)
api1(res1, stage1)
使用协程
代码语言:javascript复制import asyncio
@asyncio.coroutine
def stage(res1):
res1 = yield from api1(res1)
req2 = step1(res1)
res2 = yield from api2(req2)
req3 = step2(res2)
res3 = yield from api3(req3)
step3(res3)