2012-02-19 5 views
9

GAEでPythonを使用して簡単なWebアプリケーションを作成しようとしています。アプリは受け取った要求ごとにいくつかのスレッドを生成する必要があります。このため私はPythonのスレッドライブラリを使用しています。私はすべてのスレッドを生成し、それらを待つ。GAEのPythonスレッドが並列に実行されない

t1.start() 
t2.start() 
t3.start() 

t1.join() 
t2.join() 
t3.join() 

アプリケーションは、(各スレッドのrun()メソッドの先頭/末尾にタイムスタンプを印刷することで、これを確認した)スレッドは、直列ではなく並行して実行されているという事実を除いて細かい動作します。

application: myapp 
version: 1 
runtime: python27 
api_version: 1 
threadsafe: true 

handlers: 
- url: /favicon\.ico 
    static_files: favicon.ico 
    upload: favicon\.ico 

- url: /stylesheet 
    static_dir: stylesheet 

- url: /javascript 
    static_dir: javascript 

- url: /pages 
    static_dir: pages 

- url: .* 
    script: main.app 

が、私は私の地元のGoogleAppLauncherが好みで明示的にパスを設定することでのpython 2.7を使用していることを確認しました:私は次のようになります

マイapp.yamlをマルチスレッド有効にするhttp://code.google.com/appengine/docs/python/python27/using27.html#Multithreadingの指示に従ってきました。

スレッドの平均実行時間は2〜3秒で、URLをオープンコールして結果に対して何らかの処理を行います。

何か間違っているか、マルチスレッディングを有効にする設定がありませんか?

答えて

17

dev_appserverでこれが発生しているのですか、またはプロダクションサービスにアプリをアップロードした後ですか? GoogleAppLauncherのあなたの言及から、あなたがdev_appserverでこれを見るかもしれないように思えます; dev_appserverは本番サーバーのスレッド動作をエミュレートしません。アプリをデプロイした後はうまく動作することがわかります。 (そうでない場合は、ここにコメントを追加する。)

をもう一つのアイデア:あなたはほとんどUrlFetchのを待っている場合、あなたはUrlFetchのために非同期インターフェイスを使用して並列に多くのURLfetch呼び出しを実行できます。 http://code.google.com/appengine/docs/python/urlfetch/asynchronousrequests.html

このアプローチをスレッドを必要としません。 (それでもdev_appserverの要求は正しく並列化されませんが、実動サーバーでは正しく処理されます)

+0

ええ、ローカルインストールでのみ問題が発生していました。私のアプリをアップロードしたときにスレッドが並行して実行されました。助けてくれてありがとう。 – Nitesh

1

GAEのマルチスレッドノートは、要求の処理方法にすぎません。基本的にPythonスレッドの動作を変更するものではありません。具体的には、threading module docsの「CPython実装の詳細」注がそのまま適用されます。

またGAEのドキュメントの「サンドボックス」でノートを言及する価値があります:要求の終了時にスレッドがランタイムによって結合されます

注意、 ので、スレッドは終わりを過ぎて実行することはできません要求の

+0

感謝の意を表するNickです。だから、GAEのマルチスレッドサポートは、GAEが要求を並行して処理する複数のスレッドを生成することができますが、アプリケーションコード自体はヘルパースレッドを生成できません。 – Nitesh

+0

@ Nitesh:リクエストを手渡すフロントエンドは、アプリケーションの複数のインスタンスを生成してそれらの要求を処理することができますが、各インスタンスで作成するスレッドは通常のルールでバインドされます。もちろん、ヘルパースレッドを生成することはできますが、I/Oでブロックしていない限り、同時に実行されることはありません。 –

+0

ヘルパースレッドでは、urllib.urlopen呼び出しを行っています。このコールI/Oはブロックされていませんか? – Nitesh

0

スレッドがほとんどデータストア操作を待っている場合は、NDBモジュールを試してみてください。セマンティクスは、あなたがやっていることに十分近いでしょう。

IIRCのマルチスレッドフラグを使用すると、1つのサーバーインスタンスが別のスレッドで複数の要求を処理できますが、自分でスレッドを開始することはできません。返す前にそれらを同期させる必要がない場合は、それらを別々のtasksに置き、それらを1つまたは複数のタスクキューに委任することができます。

+2

実際、Py27ランタイムはスレッドの作成を許可しています。 (しかし、上記の最初の答えに追加された注記を見てください。要求が終わると結合されます。) –

+0

訂正してくれてありがとう、忠告してくれてありがとう。 – rbanffy

+0

「バックグラウンドスレッド」と呼ばれる新しい機能があります。通常のスレッドと似ていますが、バックグラウンドスレッドはリクエストの最後に暗黙的に結合されていません。https://developers.google.com/appengine/docs/python/backends/background_thread – allyourcode

関連する問題