Уведомления

Группа в Telegram: @pythonsu

#1 Май 29, 2013 15:16:03

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Многопоточные сетевые приложения замедляются после промежутка времени

Ну и посмотрите http://mg.pov.lt/objgraph/ - с ним проще найти утечку.



Офлайн

#2 Май 29, 2013 15:33:24

deye
Зарегистрирован: 2013-05-25
Сообщения: 10
Репутация: +  0  -
Профиль   Отправить e-mail  

Многопоточные сетевые приложения замедляются после промежутка времени

А в каком случае может не произойти захват лока? Ну кроме случая, когда он захвачен другим потоком.

Насчёт очереди с результатами - спасибо, попробую.

Исходя из кода я все таки спрошу:
Вы уверены в этом?
И что правильно ловятся, с уничтожением объектов?

Если бы все не ловились, то я бы получил их от интерпретатора, так как функция process_task в try/except не обёрнута.
А что значит ловить правильно? Уничтожение объектов вручную не делую (если вы имеете ввиду вызов метода del). Но разве сборщик мусора не должен их убить? Ведь после завершения process_task никаких внешних ссылок не остаётся (кроме самого задания).

Офлайн

#3 Май 29, 2013 16:04:15

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Многопоточные сетевые приложения замедляются после промежутка времени

deye
А в каком случае может не произойти захват лока? Ну кроме случая, когда он захвачен другим потоком.
Именно в этом случае и может.
И ваш последующий код сработает совсем не так, как вы того ожидаете.

deye
Но разве сборщик мусора не должен их убить?
И убьет.
Вопрос в том, когда он это сделает.
Если, например, через 10 минут (условно), то все эти 10 минут у вас накапливаются ссылки и занимают память.

deye
Ведь после завершения process_task никаких внешних ссылок не остаётся
Результат (память растет) противоречит этому предположению ;)



Офлайн

#4 Май 29, 2013 16:33:13

deye
Зарегистрирован: 2013-05-25
Сообщения: 10
Репутация: +  0  -
Профиль   Отправить e-mail  

Многопоточные сетевые приложения замедляются после промежутка времени

Именно в этом случае и может.
И ваш последующий код сработает совсем не так, как вы того ожидаете.

Видимо я не понимаю как работают локи. Я ожидал такого развития событий:
Если 1 поток захватило лок, то остальные потоки про попытке его захватить заблокируются, до того момента как он освободится. Далее следующий поток захватит его и так далее.
Т.е. кусок кода по записи в файл должен выполняться только одним потоком в один момент времени.

Офлайн

#5 Май 29, 2013 19:48:38

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Многопоточные сетевые приложения замедляются после промежутка времени

Все так, но вы не проверяете захватился ли лок.
И не учитываете инертность файловой системы при операциях с файлами.



Офлайн

#6 Май 29, 2013 20:00:02

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

Многопоточные сетевые приложения замедляются после промежутка времени

А как оценивается скорость работы? Запросы в секунду, еще что-то или вообще субъективно?

Просто, например, если считается общее количество заданий(запросов) и делится на время, то таймауты нескольких запросов сильно попортят значение задания/время.

Офлайн

#7 Май 29, 2013 20:09:17

deye
Зарегистрирован: 2013-05-25
Сообщения: 10
Репутация: +  0  -
Профиль   Отправить e-mail  

Многопоточные сетевые приложения замедляются после промежутка времени

Lexander, объясните, пожалуйста, что вы имеете ввиду под проверкой лока? Разве попытка захватить лок не есть проверка?

reclosedev, количество заданий в час. Таймауты в 20-30 секунд не особо будут влиять на статистику в таком случае. Тем более влиять практически на 1 порядок, как у меня

Отредактировано deye (Май 29, 2013 20:10:22)

Офлайн

#8 Май 29, 2013 23:54:06

deye
Зарегистрирован: 2013-05-25
Сообщения: 10
Репутация: +  0  -
Профиль   Отправить e-mail  

Многопоточные сетевые приложения замедляются после промежутка времени

Убрал использование локов, сделал очередь с результатами и один поток, который пишет данные из этой очереди -> Не помогло.
Кстати, возможно важную подробность забыл упомянуть: чем больше потоков, тем быстрее наступает время, после которого скорость падает. И время опять же будет всегда примерно одинаковым для одного и того же количества потоков.
Т.е. скажем если 100 потоков - скорость падает через 3 часа,
если 200 потоков - через 2 часа,
300 потоков - через час.
(данные для примера, не фактические)

Насчёт потребляемой памяти: с момента запуска до момента замедления (примерно 20 мин) употребление памяти увеличилось примерно на 5мб. Это серьёзно?

Отредактировано deye (Май 30, 2013 00:08:25)

Офлайн

#9 Май 30, 2013 12:20:34

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Многопоточные сетевые приложения замедляются после промежутка времени

deye
Lexander, объясните, пожалуйста, что вы имеете ввиду под проверкой лока?
lock.locked()
deye
Убрал использование локов, сделал очередь с результатами и один поток, который пишет данные из этой очереди -> Не помогло.
Этот совет касался других проблем, которые я описал выше.
deye
Насчёт потребляемой памяти: с момента запуска до момента замедления (примерно 20 мин) употребление памяти увеличилось примерно на 5мб. Это серьёзно?
Нет, это мало.

Сколько вы говорите у вас потоков - 100 и более?
Это может в корне изменить источник проблемы.
Специально пишу - это гипотезу, которую нужно проверить, а то мы уже с памятью начали бороться, хотя по факту, оказывается, ее мало расходуется.
Добавьте в список потенциальных причин GIL и переключения контекста между потоками - вот здесь тратится время.
Чтобы проверить эту гипотезу, проверьте время до замедления с разным количеством потоков.
Если она подтвердится,
либо уменьшить количество потоков - этот вариант подойдет, если сетевой интерфейс нагружен на 50 и более процентов;
либо переписать код на multiprocessing, twisted, asyncore и т.п. вещах

Вообще, любой IO лучше писать на потоках или асинхронно.
Сеть - это тоже IO.

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



Офлайн

#10 Май 30, 2013 16:49:46

lorien
От:
Зарегистрирован: 2006-08-20
Сообщения: 755
Репутация: +  37  -
Профиль  

Многопоточные сетевые приложения замедляются после промежутка времени

Ещё можно попробовать вместо threading заюзать multiprocessing, ну и в любом случае 100 тредов-потоков это не очень прикольно, для этого я и сделал Grab::Spider, чтобы сотни тредов или процессов не создавать.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version