yield方式转移执行权的协程之间不是调用者与被调用者的关系,而是彼此对称、平等的
http://www.geeksforgeeks.org/use-yield-keyword-instead-return-keyword-python/
def simpleGeneratorFun():
yield 1
yield 2
yield 3
for value in simpleGeneratorFun():
print(value)
print('-----')
def nextSquare():
i = 1
while True:
yield i * i
i += 1
for num in nextSquare():
if num > 100:
break
print(num)
Python yield 使用浅析 https://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/
GitHub - gevent/gevent: Coroutine-based concurrency library for Python https://github.com/gevent/gevent
gevent - 廖雪峰的官方网站 https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001407503089986d175822da68d4d6685fbe849a0e0ca35000
Python通过yield
提供了对协程的基本支持,但是不完全。而第三方的gevent为Python提供了比较完善的协程支持。
gevent是第三方库,通过greenlet实现协程,其基本思想是:
当一个greenlet遇到IO操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。
version = 3.7.4
协程创建 任务执行
Coroutines and Tasks — Python 3.7.4 documentation https://docs.python.org/3/library/asyncio-task.html#creating-tasks
# 协程通过 async/await 语法进行声明,是编写异步应用的推荐方式。
# Coroutines declared with async/await syntax is the preferred way of writing asyncio applications.
import asyncio import time, random def taskPool(): ''' 任务池 一个任务一个协程 :return: ''' return [i for i in range(random.randint(0, 32))] # 协程通过 async/await 语法进行声明,是编写异步应用的推荐方式。 # Coroutines declared with async/await syntax is the preferred way of writing asyncio applications. async def executeSingleTask(taskId, delay=10): print(f'taskId {taskId} started at {time.strftime("%X")}') await asyncio.sleep(delay) print(f'taskId {taskId} finished at {time.strftime("%X")}') async def executeAllTask(): # 获取任务 taskList, awaitList = taskPool(), [] # 异步任务创建 for taskId in taskList: task = asyncio.create_task(executeSingleTask(taskId)) awaitList.append(task) # 异步任务执行 for a in awaitList: await a asyncio.run(executeAllTask())
D:\pyCGlang\venv\异步\Scripts\python.exe D:/pyCGlang/异步/a.py taskId 0 started at 00:11:36 taskId 1 started at 00:11:36 taskId 2 started at 00:11:36 taskId 3 started at 00:11:36 taskId 4 started at 00:11:36 taskId 5 started at 00:11:36 taskId 6 started at 00:11:36 taskId 7 started at 00:11:36 taskId 8 started at 00:11:36 taskId 9 started at 00:11:36 taskId 10 started at 00:11:36 taskId 11 started at 00:11:36 taskId 12 started at 00:11:36 taskId 13 started at 00:11:36 taskId 14 started at 00:11:36 taskId 15 started at 00:11:36 taskId 16 started at 00:11:36 taskId 17 started at 00:11:36 taskId 18 started at 00:11:36 taskId 19 started at 00:11:36 taskId 20 started at 00:11:36 taskId 21 started at 00:11:36 taskId 22 started at 00:11:36 taskId 0 finished at 00:11:46 taskId 2 finished at 00:11:46 taskId 6 finished at 00:11:46 taskId 14 finished at 00:11:46 taskId 22 finished at 00:11:46 taskId 21 finished at 00:11:46 taskId 20 finished at 00:11:46 taskId 19 finished at 00:11:46 taskId 18 finished at 00:11:46 taskId 17 finished at 00:11:46 taskId 16 finished at 00:11:46 taskId 13 finished at 00:11:46 taskId 15 finished at 00:11:46 taskId 12 finished at 00:11:46 taskId 11 finished at 00:11:46 taskId 10 finished at 00:11:46 taskId 9 finished at 00:11:46 taskId 8 finished at 00:11:46 taskId 5 finished at 00:11:46 taskId 7 finished at 00:11:46 taskId 4 finished at 00:11:46 taskId 1 finished at 00:11:46 taskId 3 finished at 00:11:46 Process finished with exit code 0
效果上实现了10个任务的并行执行
import asyncio import time, random def taskPool(): ''' 任务池 一个任务一个协程 :return: ''' return [i for i in range(random.randint(0, 32))] # 协程通过 async/await 语法进行声明,是编写异步应用的推荐方式。 # Coroutines declared with async/await syntax is the preferred way of writing asyncio applications. async def executeSingleTask(taskId, delay=10): print(f'taskId {taskId} started at {time.strftime("%X")}---{time.time()}') await asyncio.sleep(delay) print(f'taskId {taskId} finished at {time.strftime("%X")}---{time.time()}') async def executeAllTask(): # 获取任务 taskList, awaitList = taskPool(), [] # 异步任务创建 for taskId in taskList: task = asyncio.create_task(executeSingleTask(taskId)) awaitList.append(task) # 异步任务执行 for a in awaitList: await a asyncio.run(executeAllTask())
D:\pyCGlang\venv\异步\Scripts\python.exe D:/pyCGlang/异步/a.py taskId 0 started at 00:28:34---1567528114.565263 taskId 1 started at 00:28:34---1567528114.565263 taskId 2 started at 00:28:34---1567528114.565263 taskId 3 started at 00:28:34---1567528114.565263 taskId 4 started at 00:28:34---1567528114.565263 taskId 5 started at 00:28:34---1567528114.565263 taskId 6 started at 00:28:34---1567528114.565263 taskId 7 started at 00:28:34---1567528114.566263 taskId 8 started at 00:28:34---1567528114.566263 taskId 9 started at 00:28:34---1567528114.566263 taskId 10 started at 00:28:34---1567528114.566263 taskId 11 started at 00:28:34---1567528114.566263 taskId 12 started at 00:28:34---1567528114.566263 taskId 0 finished at 00:28:44---1567528124.5508342 taskId 2 finished at 00:28:44---1567528124.5508342 taskId 5 finished at 00:28:44---1567528124.5508342 taskId 1 finished at 00:28:44---1567528124.5508342 taskId 4 finished at 00:28:44---1567528124.5508342 taskId 3 finished at 00:28:44---1567528124.5508342 taskId 6 finished at 00:28:44---1567528124.566835 taskId 12 finished at 00:28:44---1567528124.566835 taskId 11 finished at 00:28:44---1567528124.566835 taskId 7 finished at 00:28:44---1567528124.566835 taskId 10 finished at 00:28:44---1567528124.566835 taskId 9 finished at 00:28:44---1567528124.566835 taskId 8 finished at 00:28:44---1567528124.566835 Process finished with exit code 0
https://developers.google.com/web/fundamentals/primers/async-functions
function now(){ const c=(new Date()) +(new Date().getMilliseconds()); console.log(c); } function wait(ms) { now(); return new Promise(r => setTimeout(r, ms)); } async function parallel() { console.log("start!--->"); now(); const wait1 = wait(6000); // Start a 6000ms timer asynchronously… const wait2 = wait(6000); // …meaning this timer happens in parallel. await wait1; // Wait 6000ms for the first timer… await wait2; // …by which time this timer has already finished. console.log("<---done!"); now(); return "done!"; } parallel();
start!---> VM125:4 Thu Sep 05 2019 20:19:24 GMT+0800 (新加坡标准时间)110 VM125:4 Thu Sep 05 2019 20:19:24 GMT+0800 (新加坡标准时间)110 VM125:4 Thu Sep 05 2019 20:19:24 GMT+0800 (新加坡标准时间)110 Promise {<pending>}__proto__: Promise[[PromiseStatus]]: "resolved"[[PromiseValue]]: "done!" VM125:17 <---done! VM125:4 Thu Sep 05 2019 20:19:30 GMT+0800 (新加坡标准时间)112
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Using_promises
在 ECMAScript 2017 标准的 async/await
语法糖中,这种同步形式代码的对称性得到了极致的体现:
async function foo() { try { let result = await doSomething(); let newResult = await doSomethingElse(result); let finalResult = await doThirdThing(newResult); console.log(`Got the final result: ${finalResult}`); } catch(error) { failureCallback(error); } }