yield 异步 并行 Promise await async coroutine that uses yield as a signal to the scheduler, indicating that the coroutine will be waiting until an event (such as IO) is completed.

 

 

yield 

 

PEP 492 – Coroutines with async and await syntax | peps.python.org https://peps.python.org/pep-0492/

Abstract

The growth of Internet and general connectivity has triggered the proportionate need for responsive and scalable code. This proposal aims to answer that need by making writing explicitly asynchronous, concurrent Python code easier and more Pythonic.

It is proposed to make coroutines a proper standalone concept in Python, and introduce new supporting syntax. The ultimate goal is to help establish a common, easily approachable, mental model of asynchronous programming in Python and make it as close to synchronous programming as possible.

This PEP assumes that the asynchronous tasks are scheduled and coordinated by an Event Loop similar to that of stdlib module asyncio.events.AbstractEventLoop. While the PEP is not tied to any specific Event Loop implementation, it is relevant only to the kind of coroutine that uses yield as a signal to the scheduler, indicating that the coroutine will be waiting until an event (such as IO) is completed.

We believe that the changes proposed here will help keep Python relevant and competitive in a quickly growing area of asynchronous programming, as many other languages have adopted, or are planning to adopt, similar features: [2][5][6][7][8][10].

 

 

 

 

 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);
  }
}

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

 

 



 

 

 
posted @ 2016-08-28 13:57  papering  阅读(425)  评论(0编辑  收藏  举报