3

threadsafe: true在我的 app.yaml 中使用 Google App Engine 1.7.4 上的 Python 2.7 运行时。

我有以下代码:

@ndb.tasklet
def fn_a(container):
    ''' access datastore and mutate container '''

@ndb.tasklet
def fn_b(container):
    ''' access datastore and mutate container '''

@ndb.toplevel
def parallel_fn():
    shared_container = set()

    yield fn_a(shared_container), fn_b(shared_container)

fn_a()并且fn_b()access 和 mutateshared_container都被调用parallel_fn()shared_container是一个标准库set,因此不是线程安全的。

我应该将 mutator/accessor 方法包​​装shared_container在适当的threading标准库锁中吗?

根据我对 App Engine 的了解,每个实例都是单线程的,尽管设置了threadsafe: true. 因此threading不需要使用锁定对象吗?

初步测试表明锁不是必需的,只会增加额外的开销和死锁。似乎也不应该做以下事情

if object not in shared_container:
    yield any tasklet operation
    shared_container.add(object)

shared_container可能会在操作期间由另一行执行更新,从而yield使object not in shared_container语句可能无效。然而

if object not in shared_container:
    shared_container.add(object)
    yield any tasklet operation

绝对没问题。

4

1 回答 1

3

您不需要添加锁定代码,因为 tasklet 不在单独的线程中运行。在tasklet 文档中阅读它。

如果设置 threadsafe: true,GAE 是多线程的。启动不同的线程来处理同一实例上的多个请求。通常这不是问题,因为您应该设计您的请求处理程序以无论如何都能够跨各种服务器实例运行。

这并不真正适用于这个问题,但如果你真的测试过线程问题,请小心。我不确定,但我相信在 dev_appserver 和生产 GAE 服务器上运行的线程行为是不同的,因此请确保在两者上都进行测试。

于 2012-12-25T15:31:19.453 回答