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

Как создать потокобезопасный синглтон в python

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

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

ИЗМЕНИТЬ:

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

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

4b9b3361

Ответ 1

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

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

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

Руководство по сельдерею для djangonauts: http://django-celery.readthedocs.org/en/latest/getting-started/first-steps-with-django.html

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

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

Ответ 2

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

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

EDIT:

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

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

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