Профилирование мультипроцессов в Python
У меня есть проблема с профилированием простого многопроцессного скрипта на Python. Я попробовал следующий код:
import multiprocessing
import cProfile
import time
def worker(num):
time.sleep(3)
print('Worker:', num)
if __name__ == '__main__':
for i in range(5):
p = multiprocessing.Process(target=worker, args=(i,))
cProfile.run('p.start()', 'prof%d.prof' % i)
Я запускаю 5 процессов, и в результате cProfile создает 5 разных файлов. Каждый лог показывает только то, что происходит внутри метода start
. Как мне получить логи, профилирующие функцию worker
, чтобы увидеть, что она потратила примерно 3 секунды в каждом случае?
2 ответ(ов)
Вы профилируете запуск процесса, поэтому вы видите только то, что происходит в p.start()
, как вы и сказали — p.start()
возвращает управление только после того, как дочерний процесс запущен. Вам нужно профилировать код внутри метода worker
, который будет вызван в дочерних процессах.
Если у вас есть сложная структура процессов, и вы хотите профилировать определённую часть кода или конкретный рабочий поток процесса, вы можете использовать профайлер для сбора статистики именно там (обратите внимание на методы включения и выключения, описанные в документации: https://docs.python.org/3.6/library/profile.html#module-cProfile). Вот что вам нужно сделать:
import cProfile
def my_particular_worker_code():
pr = cProfile.Profile()
pr.enable()
# Здесь идет код, который требуется профилировать
pr.disable()
pr.print_stats(sort='tottime') # сортировка по вашему желанию
Также вы можете записать отчёты в файл.
Как изменить порядок столбцов в DataFrame?
'pip' не распознан как командa внутреннего или внешнего формата
Почему statistics.mean() работает так медленно?
Преобразование строки даты JSON в datetime в Python
Есть ли разница между поднятием экземпляра класса Exception и самого класса Exception?