[解決済み] Flask でグローバル変数はスレッドセーフか?リクエスト間でデータを共有するには?
質問
私のアプリケーションでは、共通のオブジェクトの状態がリクエストによって変更され、レスポンスはその状態に依存します。
class SomeObj():
def __init__(self, param):
self.param = param
def query(self):
self.param += 1
return self.param
global_obj = SomeObj(0)
@app.route('/')
def home():
flash(global_obj.query())
render_template('index.html')
これを開発用サーバで実行すると、1、2、3、...と表示されると思います。 100 の異なるクライアントから同時にリクエストが行われた場合、何か問題が発生する可能性はありますか? 期待される結果は、100 の異なるクライアントがそれぞれ 1 から 100 までの一意の番号を表示することです。それとも、このようなことが起こるのでしょうか?
-
クライアント 1 がクエリを実行します。
self.param
は 1 ずつ増加します。 -
return 文が実行される前に、スレッドはクライアント 2 に切り替わります。
self.param
が再びインクリメントされます。 - スレッドはクライアント 1 に切り替わり、クライアントは番号 2 を返されます、とします。
- 今度はスレッドがクライアント 2 に移動し、彼に番号 3 を返します。
クライアントが 2 つしかないので、期待される結果は 1 と 2 であり、2 と 3 ではありません。1 つの番号がスキップされました。
アプリケーションをスケールアップすると、これは実際に起こるのでしょうか? グローバル変数に代わるものとして、どのようなものを検討すべきでしょうか?
どのように解決するのですか?
この種のデータを保持するために、グローバル変数を使用することはできません。スレッドセーフでないだけでなく プロセス 安全ではありません。そして、実稼働中の WSGI サーバは複数のプロセスを生成します。リクエストを処理するためにスレッドを使用していた場合、カウントが間違っているだけでなく、どのプロセスがリクエストを処理するかによって、カウントも変わってきます。
グローバルなデータを保持するために、Flaskの外部のデータソースを使用してください。データベース、memcached、またはredisは、あなたのニーズに応じて、すべて適切な別のストレージ領域です。Pythonのデータをロードしてアクセスする必要がある場合、次のことを検討してください。
multiprocessing.Manager
. また、ユーザーごとの簡単なデータにはセッションを使用することもできます。
開発サーバはシングルスレッドとプロセスで実行することができます。各リクエストは同期的に処理されるため、説明したような動作は見られません。スレッドまたはプロセスを有効にすると、それが表示されます。
app.run(threaded=True)
または
app.run(processes=10)
. (1.0では、サーバーはデフォルトでスレッド化されています)。
WSGIサーバの中には、geventや他の非同期ワーカーをサポートするものがあります。グローバル変数は、ほとんどの競合状態に対する保護がないため、まだスレッドセーフではありません。あるワーカーが値を取得し、終了し、別のワーカーがそれを変更し、終了し、最初のワーカーもそれを変更するというシナリオはまだ可能です。
グローバルなデータを保存する必要がある場合
の間に
を保存する必要がある場合、Flaskの
g
オブジェクト
. もう一つのよくあるケースは、データベース接続を管理するトップレベルのオブジェクトです。このタイプの "global" の区別は、各リクエストに一意であり、使用されないということです。
の間で使用されないということです。
リクエストの間で使用されないこと、そしてリソースのセットアップとティアダウンを管理するものがあることです。
関連
-
[解決済み] urllib、urllib2、urllib3、requestsモジュールの違いは何ですか?
-
[解決済み] Python RequestsでJSONデータをPOSTする方法とは?
-
[解決済み】ファイル間でグローバル変数を使用する?
-
[解決済み] リストはスレッドセーフか?
-
[解決済み] 何がメソッドをスレッドセーフにするのか?そのルールは?
-
[解決済み] 非同期静的メソッドは、静的クラス変数を変更しないのであれば、スレッドセーフですか?
-
[解決済み] Pythonのインスタンス変数とクラス変数
-
[解決済み] tensorflowのCPUのみのインストールでダイナミックライブラリ 'cudart64_101.dll' を読み込めなかった
-
[解決済み] Flaskで非同期タスクを作る
-
[解決済み] pipがvirtualenvの代わりにグローバルなsite-packagesにインストールする。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] python-Flaskでグローバル変数を設定する方法は?重複
-
[解決済み] 小数点以下1桁を取得する[重複]。
-
[解決済み] データフレームをソートした後にインデックスを更新する
-
[解決済み] 値で列挙名を取得する [重複]。
-
[解決済み] Django 1.7で初期マイグレーションからマイグレートバックする方法は?
-
[解決済み] Pythonでファイルの読み込みと上書きをする
-
[解決済み] Pythonで2つの順序付きリストを比較するには?
-
[解決済み] pipがvirtualenvの代わりにグローバルなsite-packagesにインストールする。
-
[解決済み] ヒストグラム Matplotlib
-
[解決済み] タプルの代わりにリストで出力するZip