# 用装饰器来标记作为协程的函数 @asyncio.coroutine defcountdown(number, n): while n > 0: print('T-minus', n, '({})'.format(number)) yieldfrom asyncio.sleep(1) # 这里会返回一个asyncio.Future对象并将其传递给时间循环,同时暂停这一协程的执行,时间循环监听这一对象,1秒钟后,时间循环会选择刚刚这个协程,将future对象的结果返回给它,然后协程继续执行。这一过程会持续到所有的协程程序全部完成。 n -= 1
ex = futures.ThreadPoolExecutor(max_workers=2) print('main: starting') f = ex.submit(task, 5) print('main: future: {}'.format(f)) print('main: waiting for results') result = f.result() print('main: result: {}'.format(result)) print('main: future after result: {}'.format(f))
# 不按照顺序来获取结果,只要有个任务完成,就执行输出结果,上面那几个方法必须等所有任务执行完了顺序输出,而这个则是只要完成一个就输出一个 wait_for = [ ex.submit(task, i) for i inrange(5, 0, -1) ] for f in futures.as_completed(wait_for): print('main: result: {}'.format(f.result()))
deftask(n): print('{}: sleeping'.format(n)) time.sleep(0.5) print('{}: done'.format(n)) return n / 10
defdone(fn): if fn.cancelled(): print('{}: canceled'.format(fn.arg)) elif fn.done(): error = fn.exception() if error: print('{}: error returned: {}'.format( fn.arg, error)) else: result = fn.result() print('{}: value returned: {}'.format( fn.arg, result))
if __name__ == '__main__': ex = futures.ThreadPoolExecutor(max_workers=2) print('main: starting') f = ex.submit(task, 5) f.arg = 5 f.add_done_callback(done) result = f.result()
任务的取消
Future只要还未开始就能被取消,f.cancel()
任务的异常
通过f.exception()可以获取到任务抛出了什么样的异常
gevent
协程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
# 最简单的使用 import gevent
deffoo(): print('Running in foo') gevent.sleep(0) print('Explicit context switch to foo again')
defbar(abc): print('Explicit context to bar') gevent.sleep(0) print('Implicit context switch back to bar')