9

複数のスレッドからアクセスできる Django セッションに辞書を保存しています。すべてのスレッドはそのディクショナリを更新できます。スレッドは、プロセスを実行するためにディクショナリから値を取得することもできます。Django セッションはスレッド セーフなのか、それともロックやセマフォを使用する必要があるのか​​を知りたいですか?

典型的な例:

Thread1:
threadDict = request.session.get('threadDict', None)
if threadDict['stop']:
   #break the for loop exit the thread
else:
   #do some processing and update some values in thread dictionary
   threadDict['abc'] = 0
   request.session['threadDict'] = threadDict (Point1)

def someFunction():
    #this function is used to send stop signal to thread
    threadDict = request.session.get('threadDict', None)
    threadDict['stop'] = True
    request.session['threadDict'] = threadDict (Point2)

Point2更新直後のセッションでスレッド辞書をPoint1更新すると、stopスレッドを終了するためのスレッドが失われる可能性はありますか。

より詳しい情報

ajax リクエストは、4 つの異なる URL からサンプルをダウンロードする 4 つのスレッドを開始します。スレッドを使用した理由 現在ダウンロード中のサンプルと残っているサンプルをユーザーに表示したいからです。すべてのスレッドは、セッション内のディクショナリでその状態を更新します。スレッドが開始された後、2 秒ごとに ajax リクエストを作成し、セッションから辞書を取得して、スレッドの現在の状態を読み取ります。しかし、スレッドはリクエストとそのセッションから独立しているため、このアイデアは失敗しました。各 ajax リクエストには必ずセッションがありますが、そのセッションをスレッドに渡すことはできません。スレッドが開始されると、他の世界から独立しているためです (渡すことはできますが、スレッドによって処理が行われているほど速く渡すことはできません)。スレッド)。この問題に取り組むために、セッションではなくキャッシュ フレームワークを選択します。キャッシュはどこからでもアクセスできます。スレッドは状態を辞書に保存してキャッシュに戻し、2 秒ごとにキャッシュから辞書を取得して状態を読み取ります。私の経験によると、キャッシュはスレッドセーフではありません。したがって、4 つのスレッドに対して、4 つの辞書を別々に使用しました。

4

5 に答える 5

9

返されるrequest.sessionオブジェクトは、同じストレージにアクセスするすべてのリクエストに対して新しいものになります。さらに、それらは要求時にストレージからロードされ、応答時に保存されます。したがって、長時間実行スレッドから別のリクエストに情報を転送したい場合は、それを長時間実行スレッドに手動で保存する必要があります。残念ながら、これにより、同じセッションのデータへの変更が失われます。

セッションは、ある意味でスレッドセーフです。この方法でインタプリタを壊すことはありません。リクエストは、最初のアクセス時にセッション データをそのスナップショットとして表示し、保存すると、その時点以降に行われたすべての変更が上書きされます。したがって、セッション状態は一貫していますが、一部のリクエストの変更は失われる可能性があります。

実際、このプロパティは事実上すべてのフレームワークに共通です。複数のプロセス間で共有される可能性のあるセッション/キャッシュ/その他のストレージは、誰かの変更が上書きされる可能性なしに、内部に格納されているオブジェクトの変更を提供する可能性はほとんどありません。

于 2011-12-18T11:54:24.907 に答える
2

Djangoセッションは、リクエスト処理の開始時にフェッチされ、リクエスト処理の終了時に保存される辞書です[ソース]。したがって、それに並行して変更を実行すると、それらの変更の1つが優先されます。しかし、通常、人間のユーザーはそのような並列アクションを実行できず、ビジネスは続行されます。

さて、私はあなたの例を完全には理解していませんが、あなたは単にセッション辞書を悪用しようとしているようです。私はかなりの数のDjangoベースのWebサイトを開発し、Django自体の内部の制限やバグに関連する多くの問題にこだわっていますが、それでも複数のスレッドからのセッションdictをいじると、教科書の例のように見えます。セッションの誤用。

たぶん、あなたが達成しようとしていることについてもっと何かを書くとき、私たちは解決策を理解することができますか?

于 2011-12-19T02:34:26.150 に答える
0

django がスレッドセーフかどうかはわかりません。たとえば、django/core/urlresolvers.py は、プロセスごとに複数のスレッドで Apache+mod_wsgi 構成を使用する場合、スレッドセーフではありません。しかし、彼らはそれをするために働きます。一部のチケットは django チケット システム15849にあります

于 2011-11-29T22:49:49.177 に答える
-1

@Krumelur が述べたように、グローバル インターピーター ロック (GIL) のため、Python スレッドは同時に実行されません。これは欠陥であり、機能ではないため、依存しないでください。

現在の回避策は、マルチプロセッシング モジュールを使用してサブプロセスを作成することです。Process インスタンスの is_alive() 関数を使用して、サブプロセスが実行されているかどうかを確認できます。ジューシーな詳細については、ドキュメントを参照してください。

于 2011-12-23T06:59:14.240 に答える
-1

Python の基本的な型は、グローバル インタープリター lockのおかげで、一般にスレッド セーフです。このロックは、状況によっては (I/O の実行時など) に解放され、他のスレッドがアクセスできるようになります。つまり、ユーザー (アプリケーション) は、GIL を解放する可能性のある呼び出し間で一貫した状態を維持する必要があります。このようなメソッドの例は、ソケット操作のブロックです。

于 2011-11-21T13:27:35.190 に答える