Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows


Некоторые соображения по библиотеке С/С++ - часть 7


Последняя функция, которую нам нужно рассмотреть, — это _endthreadex (ее ис ходный код тоже содержится в файле Threadex.c). Вот как она выглядит в моей вер сии (в псевдокоде)

void _cdecl _endthreadex (unsigned retcode)
{
_ptiddata ptd;
// указатель на блок данных потока

// здесь проводится очистка ресурсов, выделенных для поддержки операций
// над числами с плавающей точкой (код не показан)

// определение адреса блока tiddata данного потока
ptd = _getptd();

// высвобождение блока tiddata
_freeptd(ptd);

// завершение потока
ExitThread(retcode);
}

Несколько важных моментов, связанных с _endthreadex

  • Библиотечная функция _getptd обращается к Windows-функции TlsGetValue, которая сообщает адрес блока памяти tiddata вызывающего потока
  • Этот блок освобождается, и вызовом ExttThread поток разрушается. При этом, конечно, передается корректный код завершения.

Где-то в начале главы я уже говорил, что прямого обращения к функции ExitThread следует иpбегать Это правда, и я не отказываюсь от своих слов. Тогда же я сказал, что это приводит к уничтожению вызывающего потока и не позволяет ему вернуться из выполняемой в данный момент функции А поскольку она не возвращает управление, любые созданные Вами С++-объекты не разрушаются. Так вот, теперь у Вас есть еще одна причина не вызывать ExitThread. она не дает освободить блок памяти tiddata потока, из-за чего в Вашем приложении может наблюдаться утечка памяти (до его pавершения)

Разработчики Microsoft Visual C++, конечно, прекрасно понимают, что многие все равно будут пользоваться функцией ExitThread, поэтому они кое-что сделали, чтобы свести к минимуму вероятность утечки памяти. Если Вы действительно так хотите самостоятельно уничтожить свой поток, можете вызвать из него _endthreadex (вмес то ExitTbread) и тем самым освободить его блок tiddata. И все же я не рекомендую этого

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




Начало  Назад  Вперед