Могу ли я профилировать свой код, чтобы увидеть, что создает много потоков? - PullRequest
0 голосов
/ 31 мая 2011

Я использую Embarcadero RAD Studio 2010 (C ++) и немного использовал AQTime для проверки на наличие утечек.Интересно, есть ли хороший способ точно определить происхождение в моем коде большого количества потоков, которые, кажется, никогда не умирают.Они создаются ночью, поэтому я не вижу их так, как это происходит, но я хотел бы иметь возможность вернуться назад и посмотреть, какие части кода генерировали больше потоков, и использовать эту информацию в моей детективной работе.

Ответы [ 2 ]

1 голос
/ 31 мая 2011

Я бы попробовал использовать Allocation Profiler только с одной активной областью, содержащей только класс TTHread. Начните профилирование и дайте ему сработать в одночасье. Когда вы придете на следующее утро, нажмите Получить результаты в AQtime. В результате вы увидите все экземпляры TTHread в отчете, а панель Details покажет стек вызовов создания для каждого из них. Чтобы свести к минимуму объем собираемых данных, я бы, вероятно, установил настройку «Собрать информацию о стеке» в профилировщике на «По подпрограммам» - это не даст вам номера строк, но это может быть хорошей отправной точкой для выяснения того, что происходит внутри.

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

Читайте о профилирующих областях здесь: http://smartbear.com/support/viewarticle/17895/

И проверьте описания профилировщиков здесь:

Распределение: http://smartbear.com/support/viewarticle/18030/

Функция трассировки: http://smartbear.com/support/viewarticle/17971/

Это предложение работает в вашем случае?

0 голосов
/ 31 мая 2011

Это ваш код, который создает потоки? Если это так, вы можете создать подкласс TThread (да, опять :)), переопределить ctor, чтобы зарегистрировать threadID вызывающего и извлечь из него все остальные классы потоков. Очевидно, вам нужен поточно-безопасный регистратор - у вас, вероятно, уже есть.

Если идентификатор потока вызывающей стороны ctor не очень помогает, потому что большинство ваших потоков создаются из одного потока с множеством созданий (например, основной поток GUI), я думаю, вы могли бы как-то записать адрес возврата вызывающей стороны и попробовать и разобраться, откуда пришел звонок. Столкнувшись с такой проблемой, я боюсь, что я выберу простой, недобросовестный выход, передал дополнительный целочисленный идентификатор в конструкторе потоков и отредактировал мой код так, чтобы он передавал разные идентификаторы при каждом вызове. Да, это ужасно, но это работает. У кого-то наверняка есть лучший способ. Было бы неплохо, если бы стандартный класс TThread.create в классах содержал дополнительный параметр: anObject для «передачи» в конструктор / поток, но, к сожалению, нет: ((

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

Rgds, Martin

...