Логин: Пароль:    Регистрация Всеми возможностями сайта можно пользоваться
только после авторизации.
   Забыли пароль?

Поиск
L



Статистика
u
Пользователи онлайн: нет
Гостей онлайн: 5
Всего онлайн: 5
Зарегистрировано юзеров: 7442
Комментариев на сайте: 665
Новый юзер: TravisAluch



Последние комментарии
c
Ginaneula прокомментировал "Урок 3 - Конструкция IF...THEN...ELSE":
[img]https://kapsuly-lipocarnit.ru/files/lipocarnit_1/img/product-head1.png[/img] [url=https://kapsuly-lipocarnit.ru/][img]https://karga.info/wp-content/uploads/2019/02/orig.jpg[/img][/url] Купить Липокарнит в Могилёве (Беларусь) через интернет-аптеку Функции Производитель: ООО "КоролевФарм" Форма выпуска: капсул Упаковка: полимер Объем: 72 г Срок действия: 2 года Доставка: почтой, курьером Оплата : наличными, карта Фотографии продукции Чтобы заказать Липокарнит, оставьте свои контактные данные в форме ниже, и мы свяжемся с вами как можно скорее. [url=https://kapsuly-lipocarnit.ru/]lipocarnit отзывы реальные[/url] - Мы обещаем полную анонимность. Ваши данные не будут переданы 3 людям. Внимание: внимательно проверьте введенный номер и не забудьте включить телефон, чтобы наш оператор мог с вами связаться. Левокарнитин для похудения Городская суета стимулирует постоянный стресс. Большинство людей не справляются с ними, они начинают компенсировать отвратительное настроение избытком соленой и высококалорийной пищи, что приводит к увеличению веса. Ожирение является предпосылкой других приобретенных заболеваний, таких как диабет, гипертония, склероз сосудистого русла, болезни сердца. Чтобы сохранить здоровье на долгие годы, вы должны иметь нормальный вес. Для этого есть комплекс Липокарнит. Что это за продукт Липокарнит - фармацевтический продукт, созданный российскими и швейцарскими учеными специально для лечения ожирения у пациентов с избыточным весом. Преимуществом продукта является стопроцентная натуральная композиция растительного происхождения, которая не подвергает организм чрезмерным нагрузкам при метаболизме его компонентов. Биологически активная добавка к пище доступна в форме капсул от производителя. Обмана нет Перед выпуском лечебного средства для продажи производитель выполнил медицинские тесты. Была взята контрольная группа клиентов, которые худели с помощью ежедневных физических нагрузок, правильного питания, различных органических добавок. Исследуемая группа не изменила привычного распорядка дня и образа жизни. Он просто воспринимал продукт Липокарнит. Динамика снижения веса один раз в день регистрировалась в дневнике. Данные контрольной группы были значительно ниже, чем в исследовании. Испытания и противопоказания для введения фармацевтического продукта По крайней мере, некоторые продукты имеют свои собственные ограничения на потребление. Пищевая добавка Липокарнит характеризуется небольшим перечнем противопоказаний. Отзывы Противопоказания Любая степень ожирения беременность; лактация; отвратительная переносимость фармацевтического продукта; аллергическая реакция на активные или вспомогательные компоненты препарата; Дефицит лактазы. Медицинские исследования не выявили побочных эффектов при введении биодобавки. Влияние [url=https://kapsuly-lipocarnit.ru/]липокарнит купить в могилеве[/url]а на организм Продукт положительно влияет на работу всех органов и систем пациента. Нормализует работу печени, восстанавливает ее клетки. Помогает очистить кишечный тракт, средство удаления накопившихся токсических веществ. Оказывает разрушительное действие на атеросклеротические бляшки артерий, что увеличивает их внутренний просвет. Благодаря этому эффекту улучшается питание органов и тканей, снижается риск инфаркта миокарда и инфаркта миокарда. Липокарнит снижает уровень холестерина и уровень сахара в крови. Биокомплекс повышает активность клеток мозговой ткани, ускоряет проведение нервных импульсов, улучшает память и общее самочувствие. Биоактивная добавка ускоряет клеточный метаболизм за счет истончения подкожного жира. В дополнение к этим эффектам липокарнит способен нормализовать гормональный фон организма человека. Препарат устраняет нарушение функции щитовидной железы. Многие женщины с историей гипотиреоза заметили улучшение своего общего состояния, укрепление ногтей, волос, нормализацию менструального цикла и отсутствие ночного пота при приеме Липокарнита. Состав и характеристика фармацевтического препарата Биокомплекс содержит три активных элемента. К ним относятся: липоевая кислота; L-корнитин; пиколинат хрома Основные эффекты биологических компонентов активной добавки компоненты Воздействие на организм ускоряет обмен веществ в клетках; подавляет всасывание обычных углеводов; разрушает жировые клетки, направляет энергию, выделяемую для восстановления силы тела; оказывает омолаживающее действие на кожу. облагораживает познавательные способности человека; стимулирует физическую активность пациента; снимает синдром приобретенной усталости; Способ введения энергии от расщепления жиров в конструкцию молекул белкового соединения ускоряет рост мышц. удаляет токсичные соединения, свободные радикалы, способ их абсорбции в кишечнике; снижает уровень сахара в крови; восстанавливает клетки мышечной и костной ткани. В совокупности эти три вещества выполняют регенеративную функцию для всех тканей организма. Примечание о введении биоактивных добавок Фармацевтический препарат следует употреблять потребителям с ожирением и избыточным весом по 1-2 капсулы 2 раза в день во время еды утром и вечером, запивая большим количеством воды. Вступительный курс составляет 1 месяц. Если результат не был достигнут, потребление Lipocarnitum может быть продолжено после 2-месячного перерыва. Перед введением препарата проконсультируйтесь с врачом. Не принимайте биологический комплекс самостоятельно. Где я могу найти Липокарнит Товар эксклюзивный, аналогов не имеет. В аптеке пт нет. Липокарнит можно приобрести только на нашем официальном сайте. Сейчас идет акция: фармацевтический продукт можно получить со скидкой 50% для всех посетителей. Рекламная продукция ограничена (осталось 60 упаковок). Поставщик имеет все необходимые лицензии и сертификаты для внедрения продукта. Посетите сайт производителя, закажите отличный продукт для похудения. Чтобы не покупать поддельный фармацевтический продукт, не покупайте биокомплекс в магазинах и других местах. Каждый пакет имеет свой уникальный код безопасности. Он может быть размещен на сайте производителя для проверки подлинности лечебного средства. Сколько стоит диетический продукт Общая стоимость липокарнита - 1980 руб. Цена лечебного средства со скидкой 50% составляет 990 рублей. Количество товара ограничено. Возьми комплекс по хорошей цене, сожги лишние килограммы, наслаждайся своей безупречной фигурой. Мы стараемся сделать все, чтобы вы не спали и были красивыми.
AshleyDuh прокомментировал "Урок 3 - Конструкция IF...THEN...ELSE":
[img]https://kapsuly-lipocarnit.ru/files/lipocarnit_1/img/product-head1.png[/img] [url=https://kapsuly-lipocarnit.ru/][img]https://karga.info/wp-content/uploads/2019/02/orig.jpg[/img][/url] Липокарнит в Казани Аптека 24 г. [url=https://kapsuly-lipocarnit.ru/]липокарнит для похудения[/url] - Казань, ул. Энергетиков, 3, 7 (843) 205–57–99 Таттехмедфарм г. Казань, ул. Охранники, 31/42, 7 (843) 222–00–03 Сакура, аптека № 1 г. Казань, ул. Адоратского, 1а, 7 (843) 527–61–72 Приусадебный участок г. Казань, ул. Ричард Зорге, 57, 7 (843) 204–05–60 Вита Казань, ул. Декабристы, 131, 7 (843) 239–15–20 Аккуратная аптека Казань, Сибирский тракт, 22, 7 (843) 279–50–35 Последняя покупка: просто Сейчас 99 человек смотрят этот продукт Последняя покупка: просто Сейчас 99 человек смотрят этот продукт Приготовление натуральных ингредиентов Это не лекарство и пищевая добавка Доставка : от 99 руб. укажите оператор Платеж : наличные / карта при получении Липокарнит - правильный курс для естественной потери веса до 10 кг на курс Для 90% людей с великолепными формами похудение сравнимо с изощренными пытками инквизиции. Отказ от любимых блюд, строгий контроль аппетита, ежедневные изнурительные нагрузки и постоянное нервное напряжение до следующего взвешивания. До недавнего времени через него проходили все, кто осмелился избавиться от лишнего веса в виде жира на боку, животе, бедрах и других частях тела. Но такие методы помогают только 40% людей с избыточным весом, потому что очень часто причиной его набора является не недостаточная активность или переедание, а замедление метаболических процессов. Чтобы стать победителем в борьбе за гармонию, диетологи рекомендуют покупать Липокарнит - в Казани нет других средств для похудения, которые могут деликатно и безопасно разгонять обменные процессы и сжигать жировые отложения без потери здоровья. Что такое Липокарнит, состав продукта Препарат Липокарнит - это 100% органический продукт, состоящий из активных аминокислот, способствующих расщеплению жировых клеток. Выпускается в виде желатиновых капсул, внутри которых находится белый порошок. Их удобно принимать, а активные вещества всасываются в кишечнике, отвечают за всасывание органических аминокислот. Благодаря этому активные ингредиенты полностью усваиваются. В состав препарата входит: Липоевая кислота - это органическое вещество, участвующее в переработке глюкозы и других сахаров. При ее участии утилизируются метаболиты, потенциально опасные для клеток печени, а жировые ткани превращаются в энергию и воду.Липоевая кислота показана для использования профессиональными спортсменами для улучшения метаболических процессов и поддержания физической формы. Пиколинат хрома - органическое производное триптофана, способствует образованию мышечной массы и расщеплению жира. Полезным свойством соединения при похудении является ослабление аппетита. [img]https://kapsuly-lipocarnit.ru/files/lipocarnit_1/img/review-3.jpg[/img] L-карнитин - это органическая аминокислота, которая превращает жировую ткань в энергию и воду. Дополнительным полезным свойством этого вещества является снижение уровня холестерина в крови. Аминокислота подавляет всасывание жиров в кишечнике. Средство оказывает комплексное воздействие на организм: помогает уменьшить количество жира в организме и предотвращает его повторное накопление. Как работает [url=https://kapsuly-lipocarnit.ru/]липокарнит в аптеках казани[/url] Действие препарата сильно отличается от других препаратов для похудения. Препарат не создает чувства сытости, не изменяет процесс пищеварения, но в то же время помогает избавиться от жировых отложений. Это стало возможным благодаря уникальной способности Lipocarnitum перепрограммировать обмен энергии и обмен веществ в организме. Активные вещества сами по себе не влияют на жировые клетки. Они заставляют организм активизировать свои собственные ресурсы. Результат: разрушение мембран жировых клеток; Расщепление жира - энергия и вода высвобождаются; Энергия, получаемая от сжигания жира, направляется в жизненно важные органы. Эта короткая схема содержит естественный процесс, представленный природой, но по какой-то причине нарушенный. Возвращение в состояние, естественное для здорового организма, не проходит бесследно. На фоне снижения веса нормализуются артериальное давление, уровень глюкозы в крови и холестерина. Общее состояние организма улучшается, энергия увеличивается. При использовании Липокарнита нет необходимости менять привычки питания. Тренировки в тренажерном зале также необязательны. После недели приема препарата прилив энергии будет таким, что сам организм потребует повышенной активности. С курсом приема препарат не вызывает привыкания. Тело, настроившись на режим, необходимый для похудения, продолжает бороться с лишним весом самостоятельно. Эффект длится 60 дней. Как взять Несмотря на то, что Липокарнит не продается в аптеке в Казани, применение препарата следует проводить строго по инструкции. Нарушение описанных в нем правил потенциально опасно для здоровья. Липокарнит на завтрак и ужин принимайте по 1 или 2 капсуле в зависимости от исходного веса. Курс похудения длится 30 дней. За это время наблюдается потеря веса не менее 2 кг (при небольшом лишнем весе). У тучных людей с высокой степенью ожирения потеря веса достигает до 20 кг в месяц. При необходимости дальнейшего похудения курс повторяют через 60 дней, когда предыдущий теряет силу. Побочные эффекты и противопоказания При использовании в соответствии с инструкцией побочные эффекты после приема Липокарнита не возникают. Ему также не хватает серьезных противопоказаний. Препарат подходит для похудения у диабетиков и тех, кто испытал гормональные изменения. Единственная категория людей, которым противопоказано применение препарата - это беременные и кормящие женщины. В редких случаях после применения капсул индивидуальные реакции непереносимости возникают в виде: дискомфорт в кишечнике; сыпь на коже; n; [img]https://kapsuly-lipocarnit.ru/files/lipocarnit_1/img/review-2.jpg[/img] заложенность носа. При появлении симптоматических препаратов, назначенных лечащим врачом, это поможет. Купить Липокарнит Не рекомендуется приобретать капсулы для похудения данной марки в магазинах товаров для здоровья. Производитель не поставляет препарат в розничные сети. Вы можете заказать его только у официальных представителей в интернете.Это позволило гарантировать, что цена на Липокарнит в Казани соответствует заявленной производителем, поскольку нет торговых наценок. Кроме того, при покупке у дистрибьюторов, к которым относится Аптека-5, предоставляется 100% гарантия качества и подлинности товара. В Аптеке-5 вы можете заказать Липокарнит со скидкой, пока действует акция. Постоянным клиентам предоставляются дополнительные бонусы. Вы можете совершить покупку через корзину без регистрации или заказав обратный звонок менеджера. Инструкция по применению Прием препарата Липокарнит рекомендуется в течение 30 дней. Пить по 1 или 2 капсулы в день на завтрак и ужин. При необходимости курс повторяют через 2 месяца после окончания предыдущего.

Работа с локальной памятью потока (TLS)

В данной статье мы опишем так называемую локальную память потока (TLS, Thread Local Storage).

Многие алгоритмы, которые сейчас работают в составе Windows программ, были перенесены с операционной системы MS DOS. Но операционная сисмема MS DOS по своей сути является однопоточной. поэтому использование этих алгоритмов в многопоточной среде может вызвать проблемы. Одним из таких узких мест являтеся использование процедурами и функциями глобальных переменных.

Обратимся к простому примеру. Пусть существует набор из трех процедур, которые предназначены для нахождения суммы нескольких чисел и реализованы так, как показано ниже.


   var Sum: Integer;
   
   procedure ClearSum;
   begin
     Sum := 0;
   end;
   
   procedure AddNumber(Number: Integer);
   begin
    Sum := Sum + Number;
  end;

  function GetSum: Integer;
  begin
    Result := Sum;
  end;
Очевидно, что использование этих процедур одновременно в нескольких потоках может привести к тому, что числа, переданные одним потоком, смешаются с числами, передаваемыми другими потоками, и мы не получим нужный результат. Пример того, как работает указанные выше набор процедур при многопоточности можно найти в файле TLSDemo01.dpr.

Конечно, данный пример весьма прост. К более сложным примерам можно отнести алгоритм решения системы линейных уравнений методом Гаусса, который использует глобальный массив. Попытка решить одновременно две системы в разных потоках приведет к тому, что данные в матрице исказяться и системы будут решены неправильно.

Какие же выходы из создавшегося положения, кроме как переделывания всех алгоритмов с учетом многопоточности, предоставляет нам Delphi, Win API, и как реализована в Delphi поддержка TLS - вот предмет нашего дальнейшего рассмотрения.

Использование локальной памяи потока в Delphi
Как можно решить приведенную выше проблему? Самое простое - реализовать возможность описания таких переменных, чтобы в каждом новом потоке создавалась из отдельная копия. Нетрудно догадаться, что такая возможность имеется в Delphi. Для описания таких переменных используется ключевое слово threadvar. Запустите программу TLSDemo02.dpr, чтобы убедиться в том, что она работает корректно, а ведь она отдичается от программы TLSDemo01.dpr только шестью символами в строке 6!

Из этой особенности переменных, описанных в секции threadvar, вытекают также следующие ограничения:

эти переменные не могут иметь начальное значение;
эти переменные не могут быть локальными;
к этим переменных не применима директива absolute;
при описания обычных переменных в секции absolute нельзя ссылаться на переменные threadvar.
Все сказанное проиллюстрировано ниже:
  threadvar
 
    I: Integer = 5; 
      {  Ошибка - переменная не может иметь начального
        значения }
 
    CrtMode: Byte absolute $0040; 
      {  Ошибка - к переменной неприменима директива
        absolute }

   Count: Integer; // Правильно

 var
   Reference: Integer absolute Count;
     {  Ошибка - ссылка на переменную threadvar }
 
 procedure MyProc;
 threadvar
     {  Неправильно - описание threadvar переменных в 
       процедуре }
Тем не менее, описание переменных в секции threadvar не делает их потоко-безопасными. Это, в первую очередь, применимо для всех переменных, для которых реализован механизм подсчета ссылок (строки, динамические массивы и т. д.). Рассомтрим следующий пример:
threadvar
   S1: string;
 
  var 
    S2: string;
 
  { Строки, выполняемые в первом потоке }
    S1 := 'Test';
    S2 := S1;
   ....................
   S1[3] := 'x';
 
 { Строки, выполняемые во втором потоке }
   S2 := '';  
Будем полагать, что вначале выполняться строки 8-9 первого потока, а затем одновременно выполняться строки 11 и 14. Тогда возможен следубщий сценарий:
1. Поток #1 выполняет строку 11. Он видит, что счетчик ссылок равен 2, поэтому уменьшает его на единицу (счетчик ссылок=1), но в это время прерывается.
2. Поток #2 видит, что счетчик ссылок равен единице, поэтому без заззрения совести освобождает строку, а указателю не нее присваивает nil.
3. Поток #1 пробуждается и доделывает свои манипуляции: выделяет новый фрагмент памяти, копирует в него старое содержимое строки... Но, строка уже указывает на освобожденный фрагмент памяти, что может привести к любимому всеми исключению Access violation.

Так вот, ключевое слово threadvar НЕ ДЕЛАЕТ такие пременные потоко-безопасными, и если вы хотите обращаться к переменным таких типов из разных потоков, то их работу необходимо синхронизировать.

Разработчики Delphi не рекомендуют использовать в качестве threadvar переменных указатели и процедурные типы.

Функции для работы с локальной памятью потока, предоставляемые Win32 API В Windows существует всего четыре простеньких функции для работы с локальной памятью потока. Но прежде чем их описывать, расскажем немного об основах TLS. При создании каждого потока Windows автоматически выделяет ему некоторый участок памяти, правда фиксированного размера, который содержит данные, доступные только этому потоку. Тут же храниться массив из TLS_MINIMUM_AVAIBLE указателей, который и использутся в качестве локальной памяти потока. Так что если поток хочет получить какое-то количество данных, то необходимо просто взять один из таких указателей (например нулевой), выделить ему столько памяти, сколько требуется и использовать его в качетве блока локальных переменных.

Все бы было хорошо, да только в потоко-независимых переменных иногда нуждаются и библиотеки dll. Если в программе мы можем заранее распределить все элементы массива указателей по своему усмотрению, то библиотека dll заранее не может сказать, какой же эелементов массива указателей будет свободен. Поэтому необходима функция, которая бы возвращала номер какого-либо свободного слота. Соответственно мы приходим к тому, чтобы возложить на операционную систему контроль за занятыми и свободными слотами.

Кстати, вы можете потренировать свой навык набора на виртуальной клавиатуре с армянской раскладкой по ссылке
all-armenia.com/onlajn-klaviatura-(raskladka).html

А вот и обещанные четыре функции Windows:

function TlsAlloc: DWORD; stdcall;
Функция возвращает номер свобожного элемента массива указателей, обнуляет указатель по этому индексу и меняет состояние этого элемента на занятое. Если свободных указателей больше нет, то функция вернет $FFFFFFFF.

function TlsFree(dwTlsIndex: DWORD): BOOL; stdcall;
А эта функция просто делает элемент массива указателей с номером dwTlsIndex свободным. При этом не производится никакой попытки освободить указатель с указанным индексом - эта работа, которая лежит на Вас.

function TlsGetValue(dwTlsIndex: DWORD): Pointer; stdcall;
Получаем элемент массива с индексом dwTlsIndex. В случае неудачного звершения функция вернет нулевой указатель. Но что если мы поместили по указанному индексу нулевой указатель? Тогда надо смотреть, что вернет GetLastError. Если он вернет NO_ERROR, значит действительно там храниться сейчас нулевой указатель. А иначе была ошибка. С другой стороны, если верить Джеффри Рихтеру, то в целях обеспечения скорости, в Windows не реализовано никакой проверки, свободен ли указанный элемент массива. Так что, во-первых, необходимо соблюдать осторожность при работе с TLS, а, во-вторых, необходимо поламать голову над тем, будет ли когда-нибудь такая проверка реализована в последующих версиях Windows, и стоит ли все эти проверки включать в свой код.

function TlsSetValue(dwTlsIndex: DWORD; lpTlsValue: Pointer): BOOL; stdcall;
Устанавливаем в элемент массива с индексом dwTlsIndex в значение lpTlsValue. Возвращает True при удачном завершении и False в случае ошибки. А дальше перечитайте описание функции TlsGetValue на предмет того, как реализована в Windows проверка ошибок

В заключение дадим ссылку на программу, которая выполняет все тоже, что и программа TLSDemo02.dpr, но с использованием функций Win32 API: TLSDemo03.dpr.

3. Как это реализовано в Delphi 5 Отметим, что все сказанное ниже относится к пятой версии Delphi и только к ней. Возможно, в прошлых версия это было не так, и в будущих это будет по-другому. Тогда зачем нужно это рассматривать? Ну, во-первых, изучение исходников полезно само по себе (ответ на вопрос, как это делают профессионалы). А во вторых, операторы меняются, а принципы остаются.

Все указанные ниже процедура располагаются в модуле SysInit, который можно найти в директории \Source\Rtl.

Одной из основных процедур Delphi, предназначенной для поддежки потоко-независимых переменых является _GetTLS. Эта процедура возвращает в регистре EAX указатель на блок threadvar переменных данного потока и вызывается непосредственно перед каждым обращением к потоко-независимой переменной. Вот ее реализация:

  procedure _GetTls;
  asm
          MOV     CL,ModuleIsLib 
          MOV     EAX,TlsIndex 
          TEST    CL,CL 
          JNE     @@isDll 
          MOV     EDX,FS:tlsArray 
          MOV     EAX,[EDX+EAX*4] 
          RET 

 @@initTls: 
         CALL    InitThreadTLS 
         MOV     EAX,TlsIndex 
         PUSH    EAX 
         CALL    TlsGetValue 
         TEST    EAX,EAX 
         JE      @@RTM32 
         RET 
 
 @@RTM32: 
         MOV     EAX, tlsBuffer 
         RET 
 
 @@isDll: 
         PUSH    EAX 
         CALL    TlsGetValue 
         TEST    EAX,EAX 
         JE      @@initTls 
 end;
Конечно, для новичка выглядит страшно, но... Обо всем по порядку.

1. Смотрим, эта часть кода выполняется в части dll или в части exe (переменная IsModuleLib). Если это exe, то мы возвращаем значение TlsGetValue(TlsIndex), только полученное весьма хитрым способом:
          MOV     EAX,TlsIndex 
          MOV     EDX,FS:tlsArray 
          MOV     EAX,[EDX+EAX*4] 
 
TlsIndex - это индекс блока потоко-независимых переменных для данной dll или exe-модуля. Дело в том, что фактически по смещению tlsArray=$2C расположен указатель на массив указатлей, специфичных для данного потока упомянутый нами ранее массив из TLS_MINIMUM_AVAIBLE указателей), и мы вместо вызова TlsGetValue просто обращаемся к нужному нам индексу (строка 8). Ничего предосудительного в этом нет, компиляторы Microsoft используют ту же конструкию, хотя эта возможность и недокументирована.
2. Это dll. Смотрим, что нам вернула TlsGetValue(TlsIndex) и если это не нуль, то оное значение возвращается. Иначе...

3. Попытка проинициализировать блок TLS посредством вызова InitThreadTLS. И опять проверяем, что нам вернула TlsGetValue(TlsIndex). Если не нуль, то возвращаемся, а иначе...

4. Возвращаем значение хитрой переменной TlsBuffer (Случай dll, будет рассмотрен ниже).

Для случая части exe-модуля это все. Инициализацию сегмента TLS и установку переменной TlsIndex берет на себя непосредственно загрузчик программы в Delphi, которого мы и не видим.

В случае же dll инициализацию проводит вызов происходит при подсоединении к dll нового процесса. Рассмотрим этапы инициализации и деинициализации блока TLS для dll:

Инициализация TLS (случай DLL)

Сначала исходник, а болтовня потом:

  procedure       InitThreadTLS;
  var
   p: Pointer;
  begin
   if @TlsLast = nil then
     Exit;
   if TlsIndex < 0 then
     RunError(226);
   p := LocalAlloc(LMEM_ZEROINIT, Longint(@TlsLast));
  if p = nil then
    RunError(226)
  else
    TlsSetValue(TlsIndex, p);
  tlsBuffer := p;
 end;

 procedure       InitProcessTLS;
 var
   i: Integer;
 begin
   if @TlsLast = nil then
     Exit;
   i := TlsAlloc;
   TlsIndex := i;
   if i < 0 then
     RunError(226);
   InitThreadTLS;
 end;
В обоих функциях присутствует загадочная переменная TlsLast. Компилятор всегда помещает эту переменную последней в сегменте переменных threadvar. Начало сегмента есть $00000000. Следовательно, адрес @TlsLast, используемый в обеих процедурах, есть не что иное, как суммарный размер всех потоко-независимых переменных. И @TlsLast=nil если в dll нет потоко-независимых переменных.

Что делает .InitProcessTLS? Смотрим по строкам.
1. Проверяет адрес переменной TlsLast на nil. Если это так, то никакой инициализации не требуется (строки 21-22).
2. Выполняет TlsAlloc и выполняет контроль на ошибку (строки 23-26).
3. Далее вызывается InitThreadTLS. (строка 27).
То есть, если выкинуль проверку на ошибки, процедура InitProcessTLS инициализирует переменную TlsIndex и выполняет вызов InitThreadTLS.

Что делает InitThreadTLS? Смотрим по строкам.
1. Проверяет адрес TlsLast на nil. Если это так, то выходим.
2. Проверяет на допустимость TlsIndex. (строки 7-8).
3. Производит выделение динамической памяти для блока переменных threadvar и присваевает указатель на него как в tlsBuffer, так и испотльзуя вызов TlsSetValue(TlsIndex, <значение>). (строки 9-14). Заметим, что поскольку менеджер памяти может быть еще не проинициализирован системой, то динамическая память выделяется вызовом Win API.

Обобщаем. В случае dll при подключении к ней нового процесса происходит вызов InitProcessTLS, который выполняет инициализацию переменных TlsIndex и TlsBuffer. При обращении в dll к threadvar переменным, мы пытаемся получить указатель на переменные по индексу TlsIndex, и если попытка тщетна (например, обращение к переменной было произведено в потоке в первый раз), то выполняем вызов TlsInitThread, А потом перечитываем заново указатель TlsIndex. Самое интересное, что если в этом случае мы получаем nil, то берем значение из переменной TlsBuffer. Когда это может случиться и в чем смысл мне пока неизвестно, по крайней мере в отладчике я ни разу на эти строки не попадал.

Осталась

Деинициализация TLS (случай DLL)

Опять же, вначале рассмотрим исходник:
  procedure       ExitThreadTLS;
  var
   p: Pointer;
  begin
   if @TlsLast = nil then
     Exit;
   if TlsIndex >= 0 then begin
      p := TlsGetValue(TlsIndex);
      if p <> nil then
       LocalFree(p);
   end;
 end;

 procedure       ExitProcessTLS;
 begin
   if @TlsLast = nil then
     Exit;
   ExitThreadTLS;
   if TlsIndex >= 0 then
     TlsFree(TlsIndex);
 end;
Думаю, что сокрыто за этим исходником ясно и без комментариев. ExitThreadTLS освобождает динамическую память, связанную с конкретным потоком, а ExitProcessTLS освобождает элемент массива TLS с индексом TlsIndex.

Вот и всё, Удачи!

Источник: www.thedelphi.ru
Автор: Савельев Александр
Опубликовано: 15 Июля 2017
Просмотров:


Зарегистрируйтесь или авторизуйтесь, чтобы добавлять комментарии.