2014-06-19 24 views
0

首先,我知道我可以使用线程来完成这样的任务,像这样:执行Python代码的任务蕾

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微进程,并根据他们的您可以使用它们并行执行代码。

Tasklet是一种编写并发运行函数的方法,不需要 线程; tasklet通过事件循环执行,并可以使用yield 语句暂停自己阻止I/O或某些其他操作。阻塞操作的概念被抽象为Future类,但是一个tasklet也可能产生一个RPC,以等待 RPC完成。

是否有可能完成类似上面的线程示例?

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

谢谢。

+0

注意,线程是唯一真正的平行,如果他们释放GIL,所以它有一个编译扩展与nogil被调用,I/O等 – Davidmh

+0

我看到这个演示HTTP://www.dabeaz。 com/python/GIL.pdf,它明确说明你用它得到了什么,但是在我的情况下,我可以获得更好的性能......但它仍然不能回答我的问题。 – vertazzar

+0

如果您尝试在面对请求的前面使用线程,则它们的运行时间不能超过请求生存时间。另外,如果你没有使用任何谷歌服务(rpc),你将不会得到任何真正的并发性,因为你有一个核心。我过去的测试显示没有irpc的前端线程会让速度变慢。 –

回答

0

答案取决于你的heavy_operation究竟是什么。如果heavy_operation使用RPC(远程过程调用,例如数据存储访问,UrlFetch等...),那么答案是肯定的。

how to understand appengine ndb.tasklet? 我问了一个类似的问题,你可能会在那里找到更多的细节。

我可以把任何类型的代码放在一个函数中,并将它装饰为ndb.tasklet吗?之后将其用作异步函数。或者它必须是appengine RPC?

答案

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

+0

前段时间我读过这个话题,并不明白它是否会异步执行它们。至于我的代码,不,它不会执行任何RPC调用,所以我猜它不能异步工作 – vertazzar