Меню
Главная
Авторизация/Регистрация
 
Главная arrow Технические arrow Информационные технологии arrow
Теория многозадачности и многопоточности

Локальная память потока

Глобальные переменные в многопоточных программах (так же как и любая выделенная память) разделяются между всеми потоками в программе. Локальные статические переменные функций также разделяются между всеми потоками, использующими эту функцию. Локальные автоматические переменные в функции являются уникальными для каждого потока, потому что они хранятся в стеке, а каждый поток имеет свой собственный стек.

Может возникнуть необходимость иметь постоянную область памяти, уникальную для каждого потока. Например, функция strtok языка С, которая уже упоминалась в этой главе, требует такого типа память. Нет сомнений, что С его не поддерживает. В Windows 95 имеется четыре функции, поддерживающие эту память, которая называется локальной памятью потока (thread local storage, TLS).

Первичный поток вызывает функцию JTsAlloc для получения значения индекса:

dwTlsIndex = TIsAlloc () ;

Он может храниться в глобальной переменной или может быть передан функции потока в параметре-структуре.

Функция потока начинается с выделения памяти для структуры данных и с вызова функции TIsSetValue, используя индекс, полученный ранее:

TIsSetValue (dwTlsIndex, GlobalAlloc (GPTR, sizeof (DATA))) ;

Это действие устанавливает соответствие указателя с конкретным потоком и конкретным индексом в потоке. Теперь, любая функция, которой нужно использовать этот указатель (включая саму базовую функцию потока), может использовать код, подобный такому:

PDATA pdata ;

pdata = (PDATA) TIsGetValue (dwTlsIndex) ;

Теперь она может изменять значения pdata->a и pdata->b. Перед завершением функции потока необходимо освободить захваченную память:

GlobalFree (TIsGetValue (dwTlsIndex)) ;

Когда все потоки, использующие эти данные будут завершены, первичный поток освобождает индекс:

TIsFree (dwTlsIndex) ;

Полезно посмотреть как организована локальная память потока. (Мне неизвестно, как в действительности Windows 95 это делает, но описываемая схема вполне правдоподобна.) Во-первых, функция TIsAlloc могла бы просто выделить блок памяти (длиной 0 байт) и вернуть значение индекса, который является указателем на этот блок. Каждый раз при вызове функции TIsSet Value с этим индексом блок памяти увеличивается на 8 байт с помощью функции GlobalReAlloc. В этих 8 байтах хранятся идентификатор потока, вызывающего функцию, полученный с помощью функции GetCurrentThreadID, и указатель, переданный функции TIsSetValue. Функция TIsGetValue просто использует идентификатор потока для поиска в таблице, а затем возвращает указатель. Функция TZsFree освобождает блок памяти.

 
Оригинал текста доступен для загрузки на странице содержания
< Пред   СОДЕРЖАНИЕ   След >
 

СКАЧАТЬ ОРИГИНАЛ
Теория многозадачности и многопоточности