使用ndb任务并行执行Python代码

0 投票
1 回答
710 浏览
提问于 2025-04-18 10:20

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

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

不过,在谷歌的应用引擎中,有一种叫做ndb任务的小工具,根据他们的文档,你可以用它们来并行执行代码。

任务是一个可以让你写出同时运行的函数的方法,而不需要使用线程;这些任务是通过一个事件循环来执行的,并且可以通过一个叫做yield的语句来暂停自己,以等待输入输出或其他操作。阻塞操作的概念被抽象成了Future类,但任务也可以通过yield一个RPC来等待这个RPC完成。

那么,是否可以像上面的线程示例那样实现类似的功能呢?

我已经知道如何使用get_async()来获取实体(这是我从他们的文档示例中学到的),但是关于并行代码执行的部分我还是不太明白。

谢谢。

1 个回答

0

这个回答要看你的 heavy_operation 到底是什么。如果 heavy_operation 使用了 RPC(远程过程调用,比如访问数据库、获取网址等),那么答案就是肯定的。

如何理解 appengine ndb.tasklet? 我问过一个类似的问题,你可以在那找到更多细节。

我可以在一个函数里放任何代码,然后用 ndb.tasklet 装饰它吗?之后能把它当作异步函数使用吗?还是说它必须是 appengine 的 RPC?

答案

从技术上讲是可以的,但它不会异步运行。当你用 @tasklet 装饰一个不产生结果的函数时,调用这个函数时它的 Future 值就会被计算并设置。也就是说,调用这个函数时,它会执行整个函数。如果你想实现异步操作,你必须在某个进行异步工作的地方进行“让步”。通常在 GAE 中,这会最终变成一个 RPC 调用。

撰写回答