Delphi - Что происходит с неосвобожденным (но прекращенным) потоком при выходе из приложения? - PullRequest
4 голосов
/ 09 июля 2010

У меня многопоточное приложение, и у меня есть небольшая проблема, когда приложение заканчивается: я могу правильно завершить поток, вызвав TThread.Terminate метод в обработчике Form1.OnDestroy событий, но завершение действительно занимает некоторое время, и поэтому я могу '• освободить память (TThread.Free методом).К сожалению, по какой-то другой причине для свойства TThread.FreeOnTerminate должно быть установлено значение false, чтобы объект потока не уничтожался автоматически после завершения потока.

Мой вопрос, вероятно, немного глуп, и я должен был знать его долговремя назад, но нормально ли это, и поток будет уничтожен автоматически (поскольку приложение только что закончилось), или это проблема, и память будет «потеряна»?Большое спасибо за объяснение.

Ответы [ 5 ]

7 голосов
/ 09 июля 2010

Вы должны дождаться завершения потока, прежде чем вы начнете процесс, закрывая остальную часть вашего приложения, в противном случае общие ресурсы могут быть освобождены под ногами потоков, что может привести к нарушению прав доступа,После того, как вы подождали завершения потока, вы можете освободить его.Фактически, это то, что деструктор TThread делает для вас.

Если нет общих ресурсов, тогда, конечно, дайте ему умереть самому.Даже если поток завершается после основного потока, все, что требуется, - это чтобы все ваши потоки выходили из программы для завершения.Любая память, связанная с объектом потока, будет просто очищена и возвращена ОС вместе со всем остальным.

НО , будьте осторожны!Если вашему потоку требуется некоторое время для выхода, это может привести к тому, что процесс зомби начнет работать без графического интерфейса.Вот почему очень важно проверить флаг Terminated очень часто в цикле потока и выйти из потока.

N @

4 голосов
/ 09 июля 2010

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

1 голос
/ 09 июля 2010

Поток в конце концов прекратится, и Windows очистит всю оставшуюся память. Тем не менее, вы также можете просто дождаться завершения потока, потому что это именно то, что Windows будет делать в любом случае. Ваше приложение может казаться закрытым, потому что все окна могли быть закрыты / скрыты, но процесс приложения не завершится, пока не завершатся все потоки ...

0 голосов
/ 09 июля 2010

почему вы не увеличиваете переменную при создании потока, а при событии уничтожения ждете окончания потока, уменьшаете переменную, а при определении приложения просто выполняете Application.processmessages?

почему ваш поток не свободен от завершения= правда?все общие ресурсы могут быть обработаны в критическом разделе.

наилучшими пожеланиями,

0 голосов
/ 09 июля 2010

Когда процесс завершается, ОС восстанавливает всю выделенную память и закрывает все открытые дескрипторы.Вам не нужно беспокоиться о ПАМЯТИ *), которая просачивается в особый случай закрытия приложения.ОС также закроет все ваши открытые дескрипторы **), по крайней мере, теоретически.Учитывая все это, для вас может быть безопасным просто прекратить поток (используя TerminateThread (MyThread.Handle) ) из деструктора форм, прежде чем убивать другие общие ресурсы.Задайте себе эти вопросы:

  1. Что нить делает?Безопасно ли прекратить его в любое время?Пример: если поток выполняет какую-либо запись на диск, просто небезопасно его уничтожать, поскольку вы можете хранить файлы на диске в несогласованном состоянии.
  2. Используете ли вы какие-либо ресурсы, которые не освобождаются автоматически Windows?Не могу придумать хорошего примера здесь ...

Если вы оба в безопасности, вы можете использовать TerminateThread и не ждать естественного завершения потока.Более безопасный подход может быть комбинированным, возможно, вам следует дать потоку возможность естественного завершения и, если он не завершился в течение 5 секунд, принудительно завершить его.

*) Я говорю о памятивы можете доказать только утечки при завершении процесса, например, потоки, которые вы убиваете, не давая им возможности правильно завершить работу, или глобальные одноэлементные классы, которые вы не освобождаете.Вся остальная неучтенная память должна быть отслежена и исправлена, потому что это ошибка.

**) К сожалению, операционная система Windows не без ошибок.Пример. Любой, кто работал с последовательными устройствами на платформе Windows, знает, как легко перевести последовательное устройство в «заблокированное» состояние, требуя перезагрузки, чтобы оно снова заработало.Технически это также дескриптор, завершающий обработку приложения, которое заблокировало его, должно разблокировать его.

...