【问题标题】:Executing python code in parallel with ndb tasklets与 ndb tasklet 并行执行 python 代码
【发布时间】:2014-06-19 10:04:00
【问题描述】:

首先我知道我可以使用线程来完成这样的任务,就像这样:

import Queue
import threading


# called by each thread
def do_stuff(q, arg):
    result = heavy_operation(arg)
    q.put(result)

operations = range(1, 10)

q = Queue.Queue()

for op in operations:
    t = threading.Thread(target=do_stuff, args = (q,op))
    t.daemon = True
    t.start()

s = q.get()
print s

但是,在 google app engine 中有一个叫做 ndb tasklets 的东西,根据他们的文档,你可以使用它们并行执行代码。

Tasklet 是一种编写并发运行函数的方法,无需 线程; tasklet 由事件循环执行并且可以挂起 自己使用 yield 阻塞 I/O 或其他一些操作 陈述。阻塞操作的概念被抽象为 未来的类,但一个小任务也可能产生一个 RPC 来等待 该 RPC 来完成。

是否可以通过上面的线程来完成类似示例的操作?

我已经知道如何使用 get_async() 处理检索实体(从他们在文档页面的示例中获得),但在并行代码执行方面我还不清楚。

谢谢。

【问题讨论】:

  • 请注意,线程只有在释放 GIL 时才真正并行,因此必须在带有 nogil、I/O 等的已编译扩展上调用它。
  • 我看到了这个演示文稿dabeaz.com/python/GIL.pdf,它显然说明了你得到了什么,但也许就我而言,我可以获得更好的性能......但它仍然没有回答我的问题。跨度>
  • 如果你试图在前面的请求中使用线程,它们的运行时间不能超过请求的生命周期。此外,如果您没有使用任何 google 服务 (rpc),您将不会获得任何真正的并发性,因为您只有一个核心。我过去的测试显示没有 irpc 的前端线程只会让事情变慢。

标签: python google-app-engine tasklet


【解决方案1】:

答案取决于您的heavy_operation 到底是什么。如果heavy_operation 使用RPC(远程过程调用,如数据存储访问、UrlFetch 等),那么答案是肯定的。

how to understand appengine ndb.tasklet? 我问了一个类似的问题,您可以在那里找到更多详细信息。

我可以在函数中放入任何类型的代码并将其装饰为 ndb.tasklet 吗?然后稍后将其用作异步功能。还是一定是appengine RPC?

答案

技术上是的,但它不会异步运行。当你用@tasklet 装饰一个非屈服函数时,它的Future 值会在你调用该函数时计算和设置。也就是说,当你调用它时,它会贯穿整个函数。如果你想实现异步操作,你必须屈服于做异步工作的东西。通常在 GAE 中,它会一直运行到 RPC 调用。

【讨论】:

  • 我不久前读过那个主题,但不明白它是否会异步执行。至于我的代码,不,它不会执行任何 RPC 调用,所以我猜它不能异步工作
猜你喜欢
  • 1970-01-01
  • 2016-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多