Windows для профессионалов


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


// описатель потока
// выделяется блок данных для нового потока

if ((ptd = _calloc_crt(1, sizeof(struct tiddata))) == NULl)
goto error_returnж

// инициализация блока данных
initptd(ptd);

// здесь запоминается нужная функция потока и параметр,
// который мы хотим поместить в блок данных
ptd->_initaddr = (void *) pfnStartAddr;
ptd->_initarg = pvParam;

// создание Honoio потока

thdl = (unsigned long)
CreateThread(psa, cbStack, _threadstartex, (PVOID) ptd, fdwCreate, pdwThrcadID);

if (thdl == NULl) {
// создать поток не удалось, проводится очистка и сообщается об ошибке
goto error_return;
}

// поток успешно создан; возвращается его описатель
return(thdl);

error_return:
// ошибка! не удалось создать блок данных или сам поток
_free_crt(ptd);

return((unsigned long)0L);

}

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

  • Каждый поток получает свой блок памяти tiddata, выделяемый из кучи, которая принадлежит библиотеке С/C++. (Структура tiddata определена в файле Mtdll h. Она довольно любопытна, и я привел ее на рис 6-2.)
  • Адрес функции потока, переданный _beginthreadex, запоминается в блоке памяти tiddata. Там же сохраняется и параметр, который должен быть передан этой функции.
  • Функция _beginthreadex вызывает CreateThread, так как лишь с ее помощью операционная система может создать новый поток.
  • При вызове CreateThread сообщается, что она должна начатъ выполнение нового потока с функции _threadstartex, а не с того адреса, на который указывает fnStartAddr. Кроме того, функции потока передается не параметр рvParam, а адрес структуры tiddata.
  • Если все проходит успешно, beginthreadex, как и CreateThread, возвращает описатель потока. В ином случае возвращается NULL.

    struct tiddata
    {
    unsigned long _tid; /* идентификатор потока */
    unsigned long _thandle; /* описатель потока */
    int terrno; /* значение errno */
    unsigned long tdoserrno; /* значение _doserrno */
    unsigned int _fpds; /* сегмент данных Floating Point */
    unsigned lonq _holdrand; /* зародышевое значение для rand() */



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