Python中一个非常简单的异步应用程序

3
我开始学习异步代码,并且阅读了很多资料,但是我似乎找不到非常简单的示例来自己尝试并更好地理解它。
我想编写一个简单的 Python(最好是3.5)程序,实现以下功能:
1) 调用虚拟异步函数`dummy()`,该函数只等待几秒钟并返回一些内容 2) 继续执行其他任务,直到`dummy()`返回结果 3) 获取从`dummy()`返回的值并将其放入变量中 4) 继续执行其他任务
请问如何实现这个过程?
注:抱歉如果表述不够清晰,但是我知道如何使用线程来实现这个过程。我希望使用`async-await`语句和`asyncio`模块来完成这个过程。

1
如果你真的想自己编写代码,而不是从SO社区中寻求帮助,那么你可以开始阅读有关Python异步编程的文档asyncio - agg3l
2个回答

3
为了回答你的问题,我修改了asyncio文档中的一个示例,并增加了更多你所要求的内容。详情请见:https://docs.python.org/3/library/asyncio-task.html
import asyncio

result2 = 0

async def compute(x, y):
    print("Compute %s + %s ..." % (x, y))
    await asyncio.sleep(1.0)
    result2 = x*y
    return x + y

async def print_sum(x, y):
    result = await compute(x, y)
    print("%s + %s = %s" % (x, y, result))

async def dosomethingelse():
    print("I've got a lovely bunch of coconuts")

loop = asyncio.get_event_loop()
tasks = [print_sum(1, 2),
   dosomethingelse(),
   compute(2, 4)
   ]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
print(result2)

如果您运行上面的代码,您应该看到dosomethingelse正在运行,而compute正在等待。
我发现异步编程真的很难理解。但是我认为asyncio比线程或多进程更加直观,因为所有东西都在同一个内存空间中运行,而且(像这样简单的协程)程序流程完全是顺序的。第一个任务运行直到遇到一个await,然后下一个任务有机会运行,以此类推。我强烈建议阅读模块文档,并尝试编写一些示例来探索每个主题。从协程开始,然后是链接,最后是回调。
编辑:我将保留此处内容,因为我认为这是一个很好的简单示例。如果您不同意,请评论。请注意,yield from语法是因为我当时使用的是稍早版本的Python 3。
我不记得我在看哪个教程,但这是我编写的第一个asyncio测试之一。
import asyncio

@asyncio.coroutine
def my_coroutine(task_name, seconds_to_sleep=3):
    print("{0} sleeping for: {1} seconds".format(task_name, seconds_to_sleep))
    yield from asyncio.sleep(seconds_to_sleep)
    print("{0} is finished".format(task_name))

loop = asyncio.get_event_loop()
tasks = [my_coroutine("task1", 4),
        my_coroutine("task2", 2),
        my_coroutine("task3", 10)]

loop.run_until_complete(asyncio.wait(tasks))
loop.close()

谢谢,但是:我该如何在做其他事情的同时继续进行另外的事情? - user3134477
谢谢,但我如何在运行“my_coroutine”实例时继续做其他事情?而且在使用“run_until_complete”时,我如何获得返回值呢? - user3134477
1
每次协程到达yield语句时,事件循环会将执行时间传递给另一个协程。因此,您的<b>其他</b>代码将进入另一个协程。 - intrepidhero
1
@user3134477 协程的一个很棒的特点是它们共享内存空间。这意味着您可以使用全局对象来存储结果。 - intrepidhero

1

为了回答你的问题(因为有其他方法可以实现你想要的),简单的答案如下:

import threading
import time


results = []

def dummy():
    time.sleep(2)
    results.append("This function result!")
    return

t = threading.Thread(target=dummy)
t.start()

while t.isAlive():
    print('Something')

print(results)  # ['This function result!']

1
这可能是获得该功能最简单的方法,但我相信 OP 希望使用 async 来解决问题。 - zvone
@zvone,我不明白你为什么会这样认为,因为他说:“但是我似乎找不到非常简单的示例来尝试并更好地理解它。”从这句话中,我理解他只是想要一个简单的工作示例,可以实现他在问题中所描述的内容。 - ettanany
这是我的结论,基于单词“async”的使用。但问题并不清楚。如果有一些尝试的例子,那么理解起来会更容易。 - zvone
我同意你的观点,通过例子我们可以理解 OP 试图实现什么,但是对我来说,“异步应用程序”并不意味着 asyncio - ettanany

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接