Что так плохо с threadlocals

Все в мире Django, кажется, ненавидят threadlocals (http://code.djangoproject.com/ticket/4280, http://code.djangoproject.com/wiki/CookBookThreadlocalsAndUser). Я прочитал эссе Armin по этому (http://lucumr.pocoo.org/2006/7/10/why-i-cant-stand-threadlocal-and-others), но большая часть из него зависит от threadlocals, плохо, потому что это неэлегантно.

У меня есть сценарий, где theadlocals сделает вещи значительно легче. (У меня есть приложение, где у людей будут субдомены, таким образом, все модели должны будут иметь доступ к текущему субдомену, и передача их от запросов не стоит того, если единственная проблема с threadlocals состоит в том, что они неэлегантны, или делают для хрупкого кода.)

Также много платформ Java, кажется, использует threadlocals много, поэтому как их случай отличается от Python/Django's?

21
задан Nick Bastin 19 November 2011 в 23:59
поделиться

4 ответа

I don't think there is anything wrong with threadlocals - yes, it is a global variable, but besides that it's a normal tool. We use it just for this purpose (storing subdomain model in the context global to the current request from middleware) and it works perfectly.

So I say, use the right tool for the job, in this case threadlocals make your app much more elegant than passing subdomain model around in all the model methods (not mentioning the fact that it is even not always possible - when you are overriding django manager methods to limit queries by subdomain, you have no way to pass anything extra to get_query_set, for example - so threadlocals is the natural and only answer).

18
ответ дан 29 November 2019 в 20:21
поделиться

Also a lot of Java frameworks seem to be using threadlocals a lot, so how is their case different from Python/Django 's?

CPython's interpreter has a Global Interpreter Lock (GIL) which means that only one Python thread can be executed by the interpreter at any given time. It isn't clear to me that a Python interpreter implementation would necessarily need to use more than one operating system thread to achieve this, although in practice CPython does.

Java's main locking mechanism is via objects' monitor locks. This is a decentralized approach that allows the use of multiple concurrent threads on multi-core and or multi-processor CPUs, but also produces much more complicated synchronization issues for the programmer to deal with.

These synchronization issues only arise with "shared-mutable state". If the state isn't mutable, or as in the case of a ThreadLocal it isn't shared, then that is one less complicated problem for the Java programmer to solve.

A CPython programmer still has to deal with the possibility of race conditions, but some of the more esoteric Java problems (such as publication) are presumably solved by the interpreter.

A CPython programmer also has the option to code performance critical code in Python-callable C or C++ code where the GIL restriction does not apply. Technically a Java programmer has a similar option via JNI, but this is rightly or wrongly considered less acceptable in Java than in Python.

3
ответ дан 29 November 2019 в 20:21
поделиться

You want to use threadlocals when you're working with multiple threads and want to localize some objects to a specific thread, eg. having one database connection for each thread. In your case, you want to use it more as a global context (if I understand you correctly), which is probably a bad idea. It will make your app a bit slower, more coupled and harder to test.

Why is passing it from request not worth it? Why don't you store it in session or user profile?

There difference with Java is that web development there is much more stateful than in Python/PERL/PHP/Ruby world so people are used to all kind of contexts and stuff like that. I don't think that is an advantage, but it does seem like it at the beginning.

2
ответ дан 29 November 2019 в 20:21
поделиться

Я избегаю такого рода использования threadlocals, потому что он вводит неявное нелокальное связывание. Я часто использую модели всевозможными способами, не ориентированными на HTTP (локальные команды управления, импорт / экспорт данных и т. Д.). Если я получаю доступ к некоторым данным threadlocals в models.py, теперь мне нужно найти способ гарантировать, что они всегда заполняются всякий раз, когда я использую свои модели, и это может стать довольно уродливым.

На мой взгляд, более явный код чище и более ремонтопригодный. Если модельный метод требует субдомена для работы, этот факт должен быть очевиден, если метод принимает этот субдомен в качестве параметра.

Если бы я абсолютно не мог найти способ сохранить данные запроса в threadlocals, я бы по крайней мере реализовать методы-оболочки в отдельном модуле, которые обращаются к threadlocals и вызывают методы модели с необходимыми данными.

22
ответ дан 29 November 2019 в 20:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: