Нарушение доступа TThread при прекращении / бесплатно
Я использую небольшой фрагмент кода, который иногда (очень редко) нарушает доступ при завершении / освобождении моего TThread. Я запускаю много экземпляров этих потоков, но это место, кажется, единственное, которое вызывает проблемы, и делает это только один раз каждые 500 или около того вызовов.
TThreadInheritor* Base= new TThreadInheritor(1);
try {
Base->Start();
WaitForSingleObject((HANDLE)Base->Handle, 1000);
MyBaseId = Base->scanvalue;
}__finally {
Base->Terminate();
Base->Free();
}
Это брошено в мой наконец. Мое первое предположение состояло в том, что WaitForSingleObject странным образом истекает и вызывает сбой в Terminate и Free, но я не совсем уверен, как это произойдет. Я не изменил ничего, что связано с методами Terminate/Free, когда я унаследовал от TThread.
Кто-нибудь знает, что может вызвать нарушение этих двух методов после столь небольшого количества кода?
2 ответа
Никогда не освобождай TThread
это все еще работает. Базовый класс TThread
деструктор небезопасен в этом отношении. Он делает довольно глупые вещи, которые могут вызвать проблемы. ВСЕГДА убедитесь, что TThread
полностью прекращается, прежде чем освободить его. Использовать WaitFor()
метод, или подождите, пока WaitForSingleObject()
отчеты WAIT_OBJECT_0
,
Во-первых, не используйте Base->Free()
, использование delete Base;
вместо.
Что еще более важно, вы должны позвонить Base->WaitFor()
после Terminate()
чтобы убедиться, что он действительно завершен до удаления объекта.
Base->Terminate();
Base->WaitFor();
delete Base;
В противном случае вы бы удалили объект потока (который ваш код / RTL все еще использует) преждевременно, что приведет к случайному нарушению доступа.
Или вы могли бы установить FreeOnTerminate
установите значение true и забудьте об ожидании / удалении объекта в целом (будьте осторожны с исчерпанием виртуальной памяти, хотя, если у вас слишком много потоков, так как пока нет 64-битной версии C++ Builder).