Вопрос по multithreading, python – Дамп стека следов всех активных потоков
Я пытаюсь вывести список всех активных потоков, включая текущий стек каждого из них. Я могу получить список всех потоков, используя threading.enumerate (), но я не могу найти способ добраться до стека оттуда.
Предыстория: приложение Zope / Plone сходит с ума время от времени, потребляя 100% процессорного времени и нуждается в перезапуске. У меня есть ощущение, что это цикл, который не завершается должным образом, но я не могу воспроизвести его в test-environemt для проверки. Мне удалось зарегистрировать обработчик сигнала, который может быть запущен извне, так что я могу вызвать некоторый код, как только ситуация повторяется. Если бы я мог сбросить трассировку стека для всех активных потоков, это дало бы мне понять, что идет не так. Дырочка работает на питоне 2.4 ...
Любые идеи о том, как отследить подобные ситуации, приветствуются :)
Ура, Chriss
Для Python 3.3 и выше, естьfaulthandler.dump_traceback()
.
Приведенный ниже код производит аналогичные выходные данные, но включает имя потока и может быть расширен для печати дополнительной информации.
for th in threading.enumerate():
print(th)
traceback.print_stack(sys._current_frames()[th.ident])
print()
Как указывает джиттер в предыдущем ответеsys._current_frames()
дает вам то, что вам нужно для v2.5 +. Для ленивых следующий фрагмент кода работал для меня и может помочь вам:
print >> sys.stderr, "\n*** STACKTRACE - START ***\n"
code = []
for threadId, stack in sys._current_frames().items():
code.append("\n# ThreadID: %s" % threadId)
for filename, lineno, name, line in traceback.extract_stack(stack):
code.append('File: "%s", line %d, in %s' % (filename,
lineno, name))
if line:
code.append(" %s" % (line.strip()))
for line in code:
print >> sys.stderr, line
print >> sys.stderr, "\n*** STACKTRACE - END ***\n"
2,4. Очень плохо. С Python 2.5 естьsys._current_frames()
.
Но вы могли бы попробоватьthreadframe, И если makefile доставляет вам неприятности, вы можете попробовать этоsetup.py для потокового кадра
Существует соответствующий рецепт наASPN, Ты можешь использоватьthreading.enumerate()
чтобы получить все приливы, просто вызовите _async_raise () с некоторым подходящим исключением, чтобы вызвать трассировку стека.
Просто ради полноты,Products.LongRequestLogger супер полезно для выявления узких мест, и для этого он сбрасывает трассировки стека через определенные промежутки времени.
При использовании Zope вы хотите установитьProducts.signalstack
или жеMr.Freeze; они были разработаны именно для этой цели!
Отправьте сигнал USR1 на ваш сервер Zope, и он немедленно сбросит следы стека для всех потоков на консоль. Он будет делать это, даже если все потоки Zope заблокированы.
Под капотом эти пакеты косвенно используютthreadframes
; для Python версии 2.5 и выше, когдаnot используя Zope, вы можете создать ту же функциональность, используяsys._current_frames()
функция для доступа к кадрам стека для каждого потока.
По состоянию наZope 2.12.5 эта функциональность встроена в сам Zope, и больше нет необходимости устанавливать дополнительные пакеты.
sys._current_frames()
.