Безопасен ли поток сеанса Django? - PullRequest
9 голосов
/ 21 ноября 2011

Я храню словарь в сеансе Django, который доступен нескольким потокам. Все потоки могут обновлять этот словарь, потоки также получают значения из словаря для запуска процесса. Я хочу знать, является ли сессия Django поточно-ориентированной или я должен использовать блокировки или семафоры?

Типичный пример:

Thread1:
threadDict = request.session.get('threadDict', None)
if threadDict['stop']:
   #break the for loop exit the thread
else:
   #do some processing and update some values in thread dictionary
   threadDict['abc'] = 0
   request.session['threadDict'] = threadDict (Point1)

def someFunction():
    #this function is used to send stop signal to thread
    threadDict = request.session.get('threadDict', None)
    threadDict['stop'] = True
    request.session['threadDict'] = threadDict (Point2)

Есть ли вероятность того, что когда Point2 обновит словарь потока в сеансе сразу после того, как он обновит Point1, также обновит его, то мой stop для выхода из потока будет потерян.

Подробнее

Запрос Ajax запускает четыре потока, которые загружают образцы из 4 разных URL. Почему я использовал темы? потому что я хочу показать пользователю, какие образцы в настоящее время загружаются, а какие остались. Все потоки обновят свое состояние в словаре в течение сессии. После запуска потоков я делаю ajax-запрос каждые две секунды, беру словарь из сессии и считываю текущее состояние потоков. Но эта идея не удалась, потому что потоки не зависят от запроса и их сеанса. Каждый запрос ajax определенно имеет свой сеанс, но я не могу передать этот сеанс потокам, потому что, когда они однажды начнутся, они не зависят от остального мира (может быть, я могу передать его, но я не могу передать его так быстро, как обработка выполняется потоки). поэтому, чтобы решить эту проблему, я выбираю кеш-каркас вместо сессии. так как кеш доступен из любого места. Потоки сохраняют свое состояние в словаре и помещают обратно в кеш, а через каждые две секунды я беру словарь из кеша и считываю состояние. И еще одна вещь, согласно моему опыту, кеш не является потокобезопасным. Так что для четырех тем я использовал четыре словаря по отдельности.

Ответы [ 5 ]

9 голосов
/ 18 декабря 2011

Возвращенный объект request.session будет новым для каждого запроса, обращаясь к тому же хранилищу.Кроме того, они загружаются из хранилища во время запроса и сохраняются обратно во время ответа.Поэтому, если вы хотите перенести информацию из долго работающего потока в другой запрос, вам нужно сохранить ее в давно работающем потоке вручную.К сожалению, это приведет к потере модификаций данных того же сеанса.

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

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

2 голосов
/ 19 декабря 2011

Сеанс Django - это словарь, извлекаемый в начале обработки запроса и сохраняемый обратно в конце его [ source ].Поэтому, если вы внесете в него параллельные изменения, то одно из этих изменений будет преобладать.Но обычно пользователь-пользователь не может выполнять такие параллельные действия, и бизнес просто продолжается.

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

Может быть, мы могли бы найти решение, когда вы напишете что-то еще о том, чего вы пытаетесь достичь?

0 голосов
/ 23 декабря 2011

Как упомянул @Krumelur, потоки Python не будут работать одновременно из-за глобальной блокировки интерпретатора (GIL) - это недостаток, а не функция, поэтому не полагайтесь на нее.

Текущий обходной путь - создание подпроцесса с использованием многопроцессорного модуля . Вы можете проверить и проверить, работает ли подпроцесс, используя функцию is_alive () экземпляра Process. См. Документы для сочных деталей .

0 голосов
/ 30 ноября 2011

Я не уверен, что django является потокобезопасным. Например, django / core / urlresolvers.py не является поточно-ориентированным, если вы используете конфигурацию Apache + mod_wsgi с несколькими потоками на процесс. но они работают, чтобы сделать это. некоторые билеты в системе продажи билетов Django 15849

0 голосов
/ 21 ноября 2011

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

...