處理多任務線程和協程對比
阿新 • • 發佈:2017-09-10
print har src super __main__ turn python 線程 eve
線程版處理多任務:
#!/usr/bin/env python # -*- coding:utf-8 -*- 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()
線程這裏註意:一定要把主線程進行阻塞,通過釋放GIL才能創建另一個線程,執行多任務
協程版處理多任務
import asyncio import itertools import sys @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(‘ hello‘+‘\n‘) @asyncio.coroutine def slow_function(): yield from asyncio.sleep(3) return 42 @asyncio.coroutine def supervisor(): spinner=asyncio.async(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()
協程通過創建綠程,和yield from方式執行多任務。同一時間只有一個協程 這裏的
@asyncio.coroutine 可加可不加,最好加上。只是用來聲明這是一個協程
上面兩個結果如下:
旋轉的指針thinking,三秒過後42
註意點:
關於協程,國人網上資料錯誤真是錯誤百出,看著各種解釋,不好意思,忍不住笑出聲。解釋錯誤,一傳十十傳百,唉,心痛,這也就是中國開源事業起不來的重要原因之一
特別是yield from的解釋,基本國人網上都是錯誤的
yield from 作用:
yield from在協程中的作用:把控制權交給調度程序。然後就能很好的理解上面協程的運行方式
處理多任務線程和協程對比