处理多任务线程和协程对比
线程版处理多任务:
#!/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在协程中的作用:把控制权交给调度程序。然后就能很好的理解上面协程的运行方式