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


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


нения другого потока (в том же процессе), который обращается к одной из функций библиотеки С, и та тоже заиосит какое то значение в глобальную переменную errno Смотрите, что получается когда процессор вернется к выполнению первого потока, в переменной errno окажется вовсе не то значение, которое было записано функци ей system Поэтому для решения этой проблемы нужно закрепить за каждым потоком свою переменную errno Кроме того, понадобится какой-то механизм, который позво лит каждому потоку ссылаться на свою переменную errno и нс трогать чужую

Это лишь один пример того, что стандартная библиотека С/С++ не рассчитана на многопоточные приложения Кроме errno, в ней есгь еще целый ряд переменных и функций, с которыми возможны проблемы в многопоточной среде _doserrno, strtok, _wcstok, strerror, _strerror, tmpnam, tmpfile, a<tcttme, _wascttme, gmttme, _ecvt, _Jcvt — спи сок можно продолжить

Чтобы многопоточные программы, использующие библиотеку С/С++, работали корректно, требуется создать специальную структуру данных и связать ее с каждым потоком, из которого вызываются библиотечные функции Более того, они должны знать, что, когда Вы к ним обращаетесь, нужно просматривать этот блок данных в вызывающем потоке чтобы не повредить данные в каком-нибудь другом потоке

Так откуда же система знает, что при создании нового потока надо создать и этот блок данных3 Ответ очень прост не знает и знать не хочет Вся ответственность — исключительно на Вас Если Вы пользуетесь небезопасными в многопоточной среде функциями, то должны создавать потоки библиотечной функцией _begmthreadex, а не Windows-функцией CreateThread

unsigned long _beginthreadex( void *secunty unsigned stack size unsigned (*start_address)(void *) void *arglist unsigned initflag unsigned *thrdaddr)

У функции _beginthreadGX тот же список параметров, что и у CreateTbread, но их имена и типы несколько отличаются (Группа, которая отвечает в Microsoft за разра ботку и поддержку библиотеки С/С++, считает, что библиотечные функции не долж ны зависеть от типов данных Wmdows) Как и CreateTbread, функция _beginthreadex возвращает описатель только что созданного потока Поэтому, если Вы раньше поль зовались функцией CreateThread, cc вызовы в исходном коде несложно заменить на вызовы _begtnthreadex Однако из-за некоторого расхождения в типах данных Вам придется позаботиться об их приведении к тем, которые нужны функции _begin threadex, и тогда компилятор будет счастлив Лично я создал небольшой макрос chBEGINTHREADEX, который и делает всю эту работу в исходном коде




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



Книжный магазин