【问题标题】:A very simple asynchronous application in pythonpython中一个非常简单的异步应用程序
【发布时间】:2017-03-04 22:39:40
【问题描述】:

我开始学习异步代码,也阅读了很多,但我似乎无法找到非常简单的示例来自己尝试并更好地理解它。

我想编写一个简单的 Python(最好是 3.5)程序,它执行以下操作:

1) 调用虚拟异步函数dummy(),它只等待几秒钟并返回一些内容
2) 继续做事直到dummy() 返回一些东西
3) 从dummy() 检索返回值并放入变量
4) 继续做事

我该怎么做?

编辑:
抱歉,如果不清楚,但我知道如何使用线程来做到这一点。我的目标是使用 async-await 语句和 asyncio 模块来做到这一点。

【问题讨论】:

  • 如果你真的想自己写,而不是 SO 社区的人,你可以在asyncio开始阅读 python 文档

标签: python asynchronous async-await python-3.5


【解决方案1】:

为了尝试回答您的问题,我修改了 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 运行,而计算正在等待。

我发现异步编程真的很难让我思考。但我认为 asyncio 实际上比线程或多处理更简单,因为一切都在相同的内存空间中运行,并且(使用像这样的简单协程)程序流程是完全顺序的。第一个任务一直运行,直到它遇到await,然后下一个任务有机会,依此类推。我强烈建议阅读模块文档,它非常好,并尝试编写一些示例来探索每个主题。从协程开始,然后是链接,然后是回调。

编辑:我将把它留在这里,因为我认为这是一个很好的简单示例。如果您不同意,请发表评论。请注意,yield from 语法是因为我当时使用的 python 3 版本稍旧。

我不记得我在读什么教程,但这是我写的第一个异步测试之一。

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()

【讨论】:

  • 谢谢,但是:在
  • 谢谢,但是当my_coroutine 实例正在运行时,我如何继续做其他 的事情?以及使用run_until_complete时如何获取返回值?
  • @user3134477 每次协程到达 yield 语句时,事件循环都会为另一个协程提供执行时间。所以你的 other 东西只是进入另一个协程。
  • @user3134477 协程的一大优点是它们共享内存空间。这意味着您可以使用全局对象来存储结果。
【解决方案2】:

坚持你的问题(因为还有其他方法可以实现你想要的),一个简单的答案如下:

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!']

【讨论】:

  • 这可能是获得该功能的最简单方法,但我相信 OP 想要使用 async 的解决方案
  • @zvone 我不明白你是怎么相信的,因为他说“但我似乎无法找到非常简单的例子来自己尝试并更好地理解它。”,来自 this ,我知道他只是想要一个简单的工作示例来完成他在问题中解释的内容。
  • 这是我的结论,基于单词 async 的使用。但问题并不明确。如果有一些尝试的例子,那就更容易理解了。
  • 我同意你的观点,通过一个例子我们可以理解 OP 试图实现的目标,但对我来说“异步应用程序”并不意味着 asyncio
猜你喜欢
  • 2017-09-03
  • 1970-01-01
  • 1970-01-01
  • 2014-01-22
  • 1970-01-01
  • 2014-01-11
  • 1970-01-01
  • 1970-01-01
  • 2012-04-19
相关资源
最近更新 更多