22

Django の世界では誰もがスレッドローカルを嫌っているようです ( http://code.djangoproject.com/ticket/4280http://code.djangoproject.com/wiki/CookBookThreadlocalsAndUser )。これに関するArminのエッセイを読みました( http://lucumr.pocoo.org/2006/7/10/why-i-cant-stand-threadlocal-and-others )が、そのほとんどはthreadlocalsに依存しているため、悪いですエレガントではない。

私は、theadlocals が物事を大幅に容易にするシナリオを持っています。(私は人々がサブドメインを持つアプリを持っているので、すべてのモデルが現在のサブドメインにアクセスする必要があり、リクエストからそれらを渡すことは価値がありません.コード。)

また、多くの Java フレームワークは threadlocals を多用しているようですが、それらのケースは Python/Django のものとどう違うのでしょうか?

4

5 に答える 5

22

暗黙的な非ローカル結合が導入されるため、この種のスレッドローカルの使用は避けています。私は、あらゆる種類の非 HTTP 指向の方法 (ローカル管理コマンド、データのインポート/エクスポートなど) でモデルを頻繁に使用します。models.py 内のいくつかのスレッドローカル データにアクセスする場合、モデルを使用するたびにデータが常に読み込まれるようにする何らかの方法を見つける必要があります。

私の意見では、より明示的なコードはよりクリーンで保守しやすいものです。モデルメソッドが動作するためにサブドメインを必要とする場合、メソッドがそのサブドメインをパラメーターとして受け入れるようにすることで、その事実を明らかにする必要があります。

リクエスト データをスレッドローカルに保存する方法が絶対に見つからない場合は、少なくともスレッドローカルにアクセスし、必要なデータを使用してモデル メソッドを呼び出す別のモジュールにラッパー メソッドを実装します。このようにして、models.py は自己完結型のままであり、threadlocals 結合なしでモデルを使用できます。

于 2009-12-17T20:53:51.110 に答える
18

threadlocals に問題はないと思います。はい、これはグローバル変数ですが、それ以外は通常のツールです。この目的 (ミドルウェアからの現在のリクエストに対してグローバルなコンテキストにサブドメイン モデルを格納する) のためだけに使用し、完全に機能します。

だから私は、ジョブに適切なツールを使用すると言います。この場合、スレッドローカルは、すべてのモデルメソッドでサブドメインモデルを渡すよりもアプリをはるかにエレガントにします(それが常に可能であるとは限らないという事実については言及していません-djangoをオーバーライドしている場合)たとえば、get_query_set に余分なものを渡す方法がないため、threadlocals が自然で唯一の答えです)。

于 2009-12-17T11:39:39.747 に答える
3

また、多くの Java フレームワークは threadlocals を多用しているようですが、それらのケースは Python/Django のものとどう違うのでしょうか?

CPython のインタープリターにはグローバル インタープリター ロック (GIL) があります。これは、インタープリターが一度に実行できる Python スレッドは 1 つだけであることを意味します。Python インタープリターの実装では、これを実現するために必ず複数のオペレーティング システム スレッドを使用する必要があるかどうかはわかりませんが、実際には CPython はそうしています。

Java の主なロック メカニズムは、オブジェクトのモニター ロックによるものです。これは、マルチコアまたはマルチプロセッサ CPU で複数の同時スレッドを使用できるようにする分散型のアプローチですが、プログラマーが対処しなければならないはるかに複雑な同期の問題も引き起こします。

これらの同期の問題は、「可変共有状態」でのみ発生します。状態が可変でない場合、または ThreadLocal の場合のように共有されていない場合、Java プログラマーが解決しなければならない問題は 1 つ少なくなります。

CPython プログラマーは依然として競合状態の可能性に対処する必要がありますが、より難解な Java の問題 (公開など) のいくつかはおそらくインタープリターによって解決されます。

CPython プログラマーには、GIL 制限が適用されない Python 呼び出し可能な C または C++ コードでパフォーマンスが重要なコードをコーディングするオプションもあります。技術的には、Java プログラマーは JNI を介して同様のオプションを利用できますが、これは正しいか間違っているかを問わず、Java では Python よりも受け入れがたいと考えられています。

于 2009-12-17T11:05:56.367 に答える
2

複数のスレッドで作業しているときにthreadlocalsを使用し、一部のオブジェクトを特定のスレッドにローカライズしたい場合。スレッドごとに1つのデータベース接続があります。あなたの場合、それをよりグローバルなコンテキストとして使用したいと思います(私があなたを正しく理解している場合)。これはおそらく悪い考えです。それはあなたのアプリを少し遅くし、より結合し、テストするのを難しくします。

なぜリクエストから渡す価値がないのですか?セッションやユーザープロファイルに保存してみませんか?

Javaとの違いは、Web開発はPython / PERL / PHP / Rubyの世界よりもはるかにステートフルであるため、人々はあらゆる種類のコンテキストやそのようなものに慣れているということです。それがメリットだとは思いませんが、最初はそう思われます。

于 2009-12-17T09:24:53.353 に答える
0

私は、ThreadLocal を使用することが、HTTP 要求/応答環境 (つまり、任意の Web アプリケーション) で依存性注入を実装するための優れた方法であることを発見しました。リクエストを受信したときに必要なオブジェクトをスレッドに「注入」し、応答を返すときにそれを「注入解除」するようにサーブレット フィルタを設定するだけです。

これは、XML の醜さ、Spring Jars の MB (学習曲線は言うまでもありません) がなく、不可解な繰り返しの @annotation ナンセンスがなく、多くのオブジェクト インスタンスに依存関係を個別に注入しないため、おそらくはるかに高速で、メモリの使用量が少なくなります。

ThreadLocal を使用して Hibernate セッションまたは JDO PersistenceManager をインジェクトでき​​る exPOJO フィルターのソースを開きました。

http://www.expojo.com

于 2012-01-22T11:44:12.737 に答える