Найти - Пользователи
Полная версия: [q] Twisted
Начало » Network » [q] Twisted
1 2
Андрей Светлов
sleep можно вызывать - из рабочего потока.
А еще можно смотреть в сторону reactor.callLater

tasks =

def start_next():
func, params = tasks.pop()
cb = deferToThread(func, *params)
cb.addCallback(lambda _:reactor.callLater(1, start_next))
bw
van-gog
ато сервер сильно грузит
Используй меньше потоков :-).
Вообще потоки не дают никакого выигрыша по скорости, особенно в Python, только создается отзывчивость системы.

van-gog
На скачку одной страницы уходит приблизительно 6-10 секунд.
Объясни почему является проблемой делать жто из главного потока? Насколько я помню поток не будет блокирован на все время скачки, реактор продолжит работать и продролжит выполнять параллельную (в главном же потоке) работы с сокетами и отложенными вызовами. Единственная проблема, это то что система будет мене отзывчива, тормазнута что-ли, хотя это не всегда проблема. Выгрышь - большая скорость загрузки, простота приложения, надежность (потенциально меньше ошибок).

..bw
PyCraft
Андрей Светлов
реактор уже содержит пул потоков. С максимальным размером именно в 10 штук.
Поэтому просто бомби threads.deferToThread сколько хочешь раз. Больше десяти одновременно выполняться не будет.
Т.е. Больше 10 клиентов одновременно работать не смогут?
Я где то читал, что таким же способом в twisted решается проблема блокирующих вызовов. Как в twisted реализованы неблокирующие варианты вызовов без потоков?
А то как-то не интересно получается.
Андрей Светлов
Клиентов может быть сколько угодно.
Почитай http://twistedmatrix.com/projects/core/documentation/howto/index.html - стандартную документацию. Буквально в самом начале рассказывают именно о том, как работает неблокирующий (он же для твистед и основной, и единственный) режим.
А то, вижу, каша в голове…
PyCraft
Андрей Светлов
Клиентов может быть сколько угодно.
Не спорю, что твистед только асинхронно и неблокирующе работает в основном, но…

т.к. не больше 10 потоков, а большинству юзеров потребуются потоки для обработки тяжелых запросов, то не больше 10 юзеров, даже если железо позволяет и выделен отдельный ресурс. Может быть этот предел опционален?
Большинство реальных задач требуют обращений к базе, тяжелых вычислений и т.п. и их придется запускать в потоке, через Deferred.

Объясните в чем тут хитрость.

ps. Мой английский со словарем, так что имею некоторые трудности с переводом.
Андрей Светлов
если сильно нужно, хоть:
reactor.suggestThreadPoolSize(10000)
Но даже десять тысяч - это сильно жестоко.
PyCraft
Андрей Светлов
reactor.suggestThreadPoolSize(10000)
Но даже десять тысяч - это сильно жестоко.
То что есть такой способ это отлично. Количество потоков и правда велико.
Однако, некоторые умельцы не рассматривают варианты, как заслуживающие внимания, если сокетов < 100000, а тестируют свои программы на 250000 одновременно работающих клиентов. Причем каждое обращение сопровождается запросом к базе данных… Правда, это не на Питоне и потоков там всего 3.

Вот как же без потоков в Питоне блокирующие задачи выполнять?
bw
> некоторые умельцы не рассматривают варианты, как заслуживающие внимания, если сокетов < 100000
Не очень понял как в контексте сокеты коррелируют с потоками?
Ты должен понимать что потоки в Python (из-за GIL и невозможности использовать несколько ядер/процессоров в одном процессе) все же служат не для повышения производительности, а лишь для параллельной обработки, а значит для большей отзывчивости. Если ты сделаешь 10000 потоков для обработки одновременно 10000 запросов, то твоя система будет (значительно?) сильнее тормозить нежели при использовании 10 или 2х потоков.
Сокеты от потоков не зависят. Все данные будут приниматься в главном потоке (даже частично обрабатываться), дальше ложешь их в пул потоков и забываешь. Если есть свободный поток то он берет очередную “задачу” из пула и выполняет её. Результат возвращаешь через главный поток.

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

Но на практике, как оказалось, хватает пула из 3-4 потоков, чтобы справиться с такими задачами. Просто в реальной ситуации(я переспросил этих умельцев :) ) не каждое сообщение(запрос) требует обращения к базе или других тяжелых операций в потоке. А схема традиционная, такая же как вы описываете.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB