Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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

Итак, я говорю, используйте правильный инструмент для задания, в этом случае threadlocals делают ваше приложение намного более элегантным, чем прохождение модели поддомена во всех методах модели (не говоря уже о том, что это даже не всегда возможно), когда вы переопределяют методы диспетчера django для ограничения запросов по субдомену, вы не имеете возможности передавать что-либо дополнительно в get_query_set, например, так что threadlocals - это естественный и единственный ответ).

Ответ 2

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

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

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

Ответ 3

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

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

Главный механизм блокировки Java - через блокировки объектов. Это децентрализованный подход, который позволяет использовать несколько параллельных потоков на многоядерных и/или многопроцессорных ЦП, но также создает гораздо более сложные проблемы синхронизации для программиста, с которыми приходится иметь дело.

Эти проблемы синхронизации возникают только при условии "shared-mutable state". Если состояние не изменено, или, как в случае с ThreadLocal, оно не является общим, то это одна менее сложная проблема для программиста Java.

Программисту CPython по-прежнему приходится иметь дело с возможностью условий гонки, но некоторые из более эзотерических проблем Java (например, публикации), по-видимому, решаются интерпретатором.

Программист CPython также имеет возможность кодировать критический код производительности с помощью кода C или С++ с кодом Python, где ограничение GIL не применяется. Технически Java-программист имеет аналогичный вариант через JNI, но это правильно или неправильно считается менее приемлемым в Java, чем в Python.

Ответ 4

Вы хотите использовать threadlocals, когда работаете с несколькими потоками, и хотите локализовать некоторые объекты в определенном потоке, например. с одним подключением к базе данных для каждого потока. В вашем случае вы хотите использовать его скорее как глобальный контекст (если я вас правильно понимаю), что, вероятно, является плохим. Это сделает ваше приложение немного медленнее, более сложным и сложнее тестировать.

Почему передача его из запроса не стоит? Почему бы вам не сохранить его в сеансе или в профиле пользователя?

Разница с Java заключается в том, что в веб-разработке гораздо больше состояний, чем в Python/PERL/PHP/Ruby, поэтому люди привыкли ко всем типам контекстов и тому подобному. Я не думаю, что это преимущество, но вначале оно похоже на это.

Ответ 5

Я нашел, что использование ThreadLocal - отличный способ реализовать Injection Dependency в среде HTTP-запроса/ответа (т.е. любой webapp). Вы просто настроили фильтр сервлета, чтобы "вставить" нужный объект в поток при получении запроса и "uninject" его при возврате ответа.

Это умный человек DI без всякого уродства XML, без MB of Spring Jars (не говоря уже о его кривой обучения) и без всякой загадочной повторяющейся номенклатуры @annotation и потому, что она не индивидуально вводит множество экземпляров объектов с зависимостями он, вероятно, намного быстрее и использует меньше памяти.

Он работал так хорошо, что мы открыли наш фильтр exPOJO, который может вводить сеанс Hibernate или JDO PersistenceManager с помощью ThreadLocal:

http://www.expojo.com