Нарушение доступа TThread при прекращении / бесплатно - PullRequest
1 голос
/ 05 октября 2011

Я выполняю небольшой фрагмент кода, который иногда (очень редко) нарушает доступ при прекращении / освобождении моего 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 ]

2 голосов
/ 05 октября 2011

Никогда не освобождайте TThread, который все еще работает.В этом отношении деструктор базового класса TThread небезопасен.Он делает довольно глупые вещи, которые могут вызвать проблемы.ВСЕГДА убедитесь, что TThread полностью завершен перед его освобождением.Используйте метод WaitFor() или дождитесь, пока WaitForSingleObject() сообщит WAIT_OBJECT_0.

1 голос
/ 05 октября 2011

Во-первых, не используйте Base->Free(). Вместо этого используйте delete Base;.

Что еще более важно, вы должны вызвать Base->WaitFor() после Terminate(), чтобы убедиться, что он действительно завершен до удаления объекта.

Base->Terminate();
Base->WaitFor();
delete Base;

В противном случае вы бы удалили объект потока (который ваш код / ​​RTL все еще может использовать) преждевременно, что приведет к случайному нарушению доступа.

Или вы можете установить для свойства FreeOnTerminate значение true и полностью забыть об ожидании / удалении объекта (будьте осторожны с исчерпанием виртуальной памяти, хотя, если у вас слишком много потоков, поскольку пока нет 64-битной версии C ++ Builder) ).

...