Вопрос

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

Фон:Приложение Zope/Plone время от времени выходит из строя, потребляя 100% ресурсов процессора, и его необходимо перезапустить.У меня такое ощущение, что это цикл, который не завершается должным образом, но я не могу воспроизвести его в тестовой среде для проверки.Мне удалось зарегистрировать обработчик сигнала, который можно запустить извне, поэтому я могу запустить некоторый код, как только ситуация возникнет снова.Если бы я мог сбросить трассировку стека для всех активных потоков, это дало бы мне представление о том, что пошло не так.Дырка работает на Python 2.4...

Любые идеи о том, как отслеживать подобные ситуации, приветствуются :)

Ура, Крис

Это было полезно?

Решение

При использовании Zope вы хотите установить Products.signalstack или мистер Фриз;они были разработаны именно для этой цели!

Отправьте сигнал USR1 на ваш сервер Zope, и он немедленно выгрузит трассировку стека для всех потоков на консоль.Он сделает это, даже если все потоки Zope заблокированы.

Под капотом эти пакеты косвенно используют threadframes;для Python версии 2.5 и выше, когда нет используя Zope, вы можете создать ту же функциональность, используя sys._current_frames() функция для доступа к кадрам стека для каждого потока.

По состоянию на Зопе 2.12.5 эта функциональность интегрирована в сам Zope, и больше нет необходимости устанавливать дополнительные пакеты.

Другие советы

Как указывает дрожание в более раннем ответе sys._current_frames() дает вам то, что вам нужно для версии 2.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"

Для Python 3.3 и более поздних версий существует faulthandler.dump_traceback().

Код ниже выдает аналогичный результат, но включает имя потока и может быть расширен для вывода дополнительной информации.

for th in threading.enumerate():
    print(th)
    traceback.print_stack(sys._current_frames()[th.ident])
    print()

2.4.Очень жаль.Начиная с Python 2.5, есть sys._current_frames().

Но ты мог бы попробовать резьбовая рамка.И если make-файл вызывает у вас проблемы, вы можете попробовать это setup.py для потокового фрейма

Пример вывода при использовании threadframe

Просто для полноты картины, Продукты.LongRequestLogger очень полезен для выявления узких мест и для этого создает дампы трассировок стека через определенные промежутки времени.

Есть подходящий рецепт АСПН.Вы можете использовать threading.enumerate() чтобы получить все tids, просто вызовите _async_raise() с каким-нибудь подходящим исключением, чтобы принудительно выполнить трассировку стека.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top