Python: штраф за спящие темы

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

Предыстория: я реализую интернет-магазин, используя django /satchmo. Требование об отсрочке платежа. Клиент может зарезервировать продукт и позволить третьей стороне оплатить его позднее (через случайный и уникальный URL-адрес).

Чтобы обработать отмену бронирования предмета, я создаю нить, которая будет спать в течение времени резервирования, а затем удалит резервирование /пометит товар как проданный, когда он проснется. Это выглядит так:

#Reserves a product when it is placed in the cart
def reserve_cart_product(product):
  log.debug("Reserving %s" % product.name)
  product.active = False
  product.featured = False
  product.save()
  from threading import Timer
  Timer(CART_RESERVE_TIME, check_reservation, (product,)).start()

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

Итак, мой вопрос к вам так:

Будет ли большое количество спящих потоков серьезно влиять на производительность? Существуют ли лучшие методы для планирования одного события в будущем. Я хотел бы сохранить это в Python, если это возможно; нет вызова at или cron через sys

На сайте не очень высокий трафик; (щедрый) верхний предел для товаров, заказанных в неделю, будет около 100. В сочетании с резервированием корзины, это может означать, что в любой момент времени может быть более 100 спящих потоков. Буду ли я сожалеть о планировании задач таким образом?

Спасибо

6 голосов | спросил pisswillis 1 FebruaryEurope/MoscowbMon, 01 Feb 2010 20:09:20 +0300000000pmMon, 01 Feb 2010 20:09:20 +030010 2010, 20:09:20

3 ответа


0

Я не вижу причин, почему это не должно работать. Базовый код для Timer (в threading.py) просто использует time.sleep. Как только он ждет некоторое время, он в основном выполняет цикл с time.sleep (0,05). Это должно привести к тому, что загрузка ЦП в основном составит 0%, даже с сотнями потоков. Вот простой пример, где я заметил, что 0% использования процессора для процесса python:

import threading

def nothing():
    pass

def testThreads():
    timers = [threading.Timer(10.0, nothing) for _ in xrange(881)]
    print "Starting threads."
    map(threading.Thread.start, timers)
    print "Joining threads."
    map(threading.Thread.join, timers)
    print "Done."

if __name__ == "__main__":
    testThreads()

Реальная проблема в том, что вы не сможете запустить слишком много потоков. В моей 64-битной системе 4 ГБ, я могу только запустить 881 поток, прежде чем я получу ошибку. Если у вас действительно будет всего несколько сотен, я не могу себе представить, что это не сработает.

ответил Daniel G 1 FebruaryEurope/MoscowbMon, 01 Feb 2010 20:45:43 +0300000000pmMon, 01 Feb 2010 20:45:43 +030010 2010, 20:45:43
0

100 потоков - это не проблема, но, как отметил tgray , что произойдет, если сервер выйдет из строя (отключение питания, плановое обслуживание, сбой оборудования и т. д.)?

Вам нужно где-то хранить информацию о бронировании в вашей базе данных.

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

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

ответил John La Rooy 1 FebruaryEurope/MoscowbMon, 01 Feb 2010 23:48:53 +0300000000pmMon, 01 Feb 2010 23:48:53 +030010 2010, 23:48:53
0

Обычно спящие потоки не имеют никаких накладных расходов, кроме памяти, выделенной для их стеков и других личных данных. Современные алгоритмы планирования операционной системы имеют сложность O (1), поэтому даже работающий поток не вносит накладных расходов, кроме объема памяти. В то же время сложно представить эффективный дизайн, требующий большого количества потоков. Единственный случай, который я могу себе представить, это общение со многими другими сверстниками. В этом случае следует использовать асинхронный ввод-вывод.

ответил David Gruzman 1 FebruaryEurope/MoscowbMon, 01 Feb 2010 20:55:39 +0300000000pmMon, 01 Feb 2010 20:55:39 +030010 2010, 20:55:39

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

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132