3

app.yamlでGoogleAppEngine1.7.4でPython2.7ランタイムを使用してthreadsafe: trueいます。

私は次のコードを持っています:

@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()変異の両方shared_containerがあり、で呼び出されparallel_fn()ます。shared_containerは標準ライブラリsetであるため、スレッドセーフではありません。

のミューテイタ/アクセサメソッドをshared_container適切なthreading標準ライブラリロックでラップする必要がありますか?

App Engineについて私が理解していることから、設定にもかかわらず、各インスタンスはシングルスレッドですthreadsafe: true。したがって、threadingロックオブジェクトの使用は必要ありませんか?

予備テストでは、ロックは不要であり、デッドロックだけでなくオーバーヘッドも追加されることが示されています。また、次のことはすべきではないようです

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

操作shared_container中に別の実行行によって更新される可能性があるため、ステートメントが無効になる可能性があります。でもyieldobject not in shared_container

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

絶対に大丈夫でしょう。

4

1 に答える 1

3

タスクレットは別のスレッドで実行されないため、ロック コードを追加する必要はありません。タスクレットのドキュメントでそれについて読んでください。

threadsafe: true を設定すると、GAE はマルチスレッド化されます。同じインスタンスで複数のリクエストを処理するために、異なるスレッドが起動されます。とにかく、さまざまなサーバー インスタンス間で実行できるように要求ハンドラーを設計する必要があるため、通常、これは問題ではありません。

これはこの質問には当てはまりませんが、実際にスレッドの問題をテストする場合は注意してください。確かではありませんが、スレッドの動作は dev_appserver と実稼働の GAE サーバーで実行すると異なると思われるため、必ず両方でテストしてください。

于 2012-12-25T15:31:19.453 に答える