Как создать потокобезопасный синглтон в Python - PullRequest
12 голосов
/ 16 июня 2011

Я бы хотел сохранить текущие потоки в моем приложении Django. Поскольку я не могу сделать это в модели или на сеансе, я подумал о том, чтобы держать их в одном месте. Я проверял это какое-то время и не нашел для этого хорошего руководства.

Кто-нибудь знает, как создать потокобезопасный синглтон в Python?

РЕДАКТИРОВАТЬ:

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

Суть в том, что у меня есть вычисление FAT, которое я хочу выполнить на стороне сервера, в разных потоках, пока пользователь использует мой сайт.

Ответы [ 2 ]

3 голосов
/ 16 июня 2011

Если у вас нет очень веских причин - вам следует запускать долго работающие потоки в другом процессе и использовать Celery для их выполнения:

Celery - асинхронный с открытым исходным кодом очередь задач / очередь заданий на основе распределенная передача сообщений. это сосредоточены на работе в режиме реального времени, но также поддерживает планирование.

Блоки выполнения, называемые задачами, являются выполняется одновременно на одном или нескольких рабочие узлы, использующие многопроцессорность, Eventlet или Gevent. Задачи могут выполнять асинхронно (в фоновом режиме) или синхронно (дождитесь готовности).

Руководство по сельдерею для джангонавтов: http://django -celery.readthedocs.org / en / latest / Getting-Start / First-steps-with-django.html

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

Обновление : для вашего случая использования определите модель Computation с полем status. Когда пользователь запускает вычисление, создается экземпляр, и запускается задача. Задача будет контролировать поле status (время от времени проверяйте db). Когда пользователь снова нажимает кнопку, представление изменит статус на user requested to stop, что приведет к завершению задачи.

1 голос
/ 16 июня 2011

Если вам нужен асинхронный код в веб-приложении, значит, вы выбрали неправильный подход.Вам следует запускать фоновые задачи с помощью специальной очереди задач, например Celery: http://celeryproject.org/

Самая большая проблема, с которой вы столкнулись, - это архитектура веб-сервера.Если вы не идете вразрез с рекомендуемой конфигурацией веб-сервера Django и не используете MPM рабочего потока, у вас не будет возможности отслеживать обработки потоков между запросами, поскольку каждый запрос обычно занимает свой собственный процесс.Вот как обычно работает Apache: http://httpd.apache.org/docs/2.0/mod/prefork.html

РЕДАКТИРОВАТЬ:

В свете ваших изменений, я думаю, вы могли бы узнать больше, создав собственное решение, которое делает это:

  • Поддерживает состояние запуска / остановки в базе данных
  • Создание новой программы, которая запускается как демон
  • Периодически проверяйте состояние запуска / остановки и начинайте или заканчивайте работу отсюда

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

...