многопоточность — Visual Studio C ++: что создает эти потоки?

Я использую потоки в течение 20 лет в Unix и просто изучаю их в Windows с Visual Studio 2008.

Мое приложение представляет собой основанный на диалогах MFC GUI с четырьмя основными «равноправными» окнами (ни одно из них не является «главным» окном). Когда MyApp :: InitInstance () запускается, окно Debug-> Windows-> Threads сообщает только об одном потоке MainThread. Когда я прохожу мимо первый CDialog::Create() вызов, 3 рабочих потока созданы. Я не знаю, что это такое, и я бы с удовольствием — и особенно хотел бы иметь ссылку на книгу с полным объяснением или веб-страницу. Я пытался поставить точку останова на CreateThread() но VS2008 сообщает: The function cannot be found. в наведении ! значок в окне точек останова. Я также не могу сделать один шаг, если нарушу функцию, которая ее вызывает. Я предполагаю, что это системный вызов, и как код ядра VS08 не может проникнуть в него.

Затем я создаю рабочий поток, который выводит аудио и для которого установлено значение THREAD_PRIORITY_TIME_CRITICAL. Это работало стабильно в течение длительного времени.

Однако, как только мое приложение покидает MyApp :: InitInstance (), возникает таинственная нить созданный с «Приоритетом», показанным как -8 в окне Отладочных потоков. Я не знаю, что это за нить. Любые идеи или указатели на ресурсы? Я пытался поставить точку останова на SetThreadPriority(), предполагая, что я ударил бы это в любом коде, устанавливая его на этот не ванильный приоритет, и так же, как CreateThread(), это не известная функция.

И что касается самой проблемы, в отличие от простой загадки: закрывая свое приложение, я уничтожаю и освобождаю всю память, которую я использовал, и получаю сбой в этом потоке «-8», пока я делаю это. Там нет источника, только сборка, и нет трассировки стека или символов. Нет никаких намеков на то, что программа повреждает кучу, например, символы появляются в ее стеке или в окне вывода.

Единственная дополнительная информация, которую я могу дать о приложении, это то, что:

— он принимает события MIDI хорошо и имеет в течение многих лет

— имеет один рабочий поток, вычисляющий данные для звукового буфера; Я установил дозорный булевский флаг и жду, пока он закончится GetExitCodeThread(); Я действительно получил код выхода, так что я уверен, что это не поток -8. (И в любом случае его приоритет — TimeCritical, а не -8)

— все без проблем, за исключением утечек памяти, которые я сейчас решаю, используя _CRTDBG_MAP_ALLOC , Без освобождения данных у меня не происходит сбоя. Но выяснив, какой именно объект вызывает проблему, я все еще в растерянности, потому что — опять же — я фактически не создал поток, который ссылается на этот объект.

1

Решение

Многие библиотеки, включая MFC, создают дополнительные рабочие потоки или пулы потоков как часть их нормальной работы. Это не о чем беспокоиться.

Если вы действительно хотите точно знать, где создаются эти потоки, проблема с настройкой точки останова на CreateThread в том, что отладчик не может разрешить имя символа. Вы должны помочь ему, сообщив, в каком модуле он находится, используя специальный синтаксис {,,module}symbol (подробнее об этом Вот). Кроме того, имя может быть украшено, поэтому действительное имя символа, которое работает, может быть любым из {,,kernel32.dll}CreateThread, {,,kernel32.dll}_CreateThread}, или же {,,kernel32.dll}_CreateThread@44, Аналогично для SetThreadPriority(),

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

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

2

Другие решения

Благодаря вашей помощи в выяснении, как создать точку прерывания создания потока. Сразу стало ясно, что он создается внутри библиотеки обработки аудио. Когда кто-то дает этой библиотеке блок памяти, содержащий сэмплы для воспроизведения, и у меня была свободная игра, это был главный кандидат.

Читая между строк в документации Microsoft, я обнаружил две дополнительные функции, которые могут потенциально закрыть такой поток waveOutReset() а также waveOutClose(), После их вызова нарушения доступа исчезли. С этим типом ошибки трудно быть уверенным, но для меня это кажется вероятной причиной проблемы.

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

0

По вопросам рекламы [email protected]