Создание многопоточных приложений. Копытин А.В - 14 стр.

UptoLike

Составители: 

14
цессорное время будет отдано другому потоку, который также вызовет эту
процедуру для установки своей строки. И к тому времени , когда операционная
система передаст обратно процессорное время первому потоку, значение пере-
менной GlobalStr будет безнадежно утрачено .
Для ситуаций, подобных описанной выше, в Win32 предусмотрено средство ,
известное под названием хранение локальных данных потоков (thread-local
storage), с помощью которого можно создавать отдельные копии глобальных
переменных для каждого действующего потока. Delphi великолепно инкапсу-
лирует это средство с помощью зарезервированного слова threadvar. От вас
требуется лишь объявить любые глобальные переменные, которые вы собирае-
тесь использовать отдельно для каждого потока, внутри блока threadvar (вместо
var) и делу конец . Переопределение переменной GlobalStr проще пареной
репы :
threadvar GlobalStr: String;
Модуль , представленный в листинге 2, иллюстрирует именно эту проблему.
Вам предлагается разобраться в главном модуле приложения Delphi, на форме
которого содержится всего одна кнопка. При щелчке на этой кнопке вызывает-
ся процедура для установки, а затем и для отображения значения переменной
GlobalStr. После этого создается другой поток, в котором устанавливается и
отображается его собственное значение этой переменной. После создания вто -
ричного потока первичный вновь вызывает процедуру SetShowStr для отобра-
жения переменной GlobalStr.
Попробуйте запустить это приложение, сначала объявив переменную
GlobalStr с помощью зарезервированного слова var, а затем threadvar, и
проанализируйте различие в результатах работы .
Листинг 2. Модуль MAIN.PAS демонстрация хранения локальных пере-
менных потоков
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TMainForm = class(TForm)
Buttonl: TButton;
procedure ButtonlClick(Sender: TObject);
private
{ Закрытые объявления }
public
{ Открытые объявления } end;
var
MainForm: TMainForm;
Implementation
{ $R *.DFM}
                                        14
цессо рно е время будето тдано друго му по току, ко торы й такж е вы зо вет эту
про цедуру для устано вки сво ей стро ки. И к тому времени, ко гдао перацио нная
система передасто братно про цессо рно е время перво му по току, значение пере-
менно й GlobalStr будетбезнадеж но утрачено .
   Д ля ситуац ий, по до бны х о писанно й вы ш е, в Win32 предусмо трено средство ,
известно е по д названием хр анение локальны х данны х пот оков (thread-local
storage), с по мо щ ью ко торо го мо ж но со здавать о тдельны е ко пии гло бальны х
переменны х для каж до го действую щ его по тока. Delphi велико лепно инкапсу-
лируетэто средство с по мо щ ью зарезервиро ванно го сло ва threadvar. О твас
требуется лиш ьо бъ явить лю бы е гло бальны е переменны е, ко торы е вы со бирае-
тесьиспо льзо ватьо тдельно для каж до го по тока, внутри бло каthreadvar (вместо
var) – и дел  у ко нец . П ерео пределение переменно й GlobalStr про щ е парено й
репы :
threadvar GlobalStr: String;
   М о дуль, представленны й в листинге 2, иллю стрируетименно эту про блему.
В ам предлагается разо браться в главно м мо дуле прило ж ения Delphi, на фо рме
ко торо го со держ ится всего о днакно пка. П ри щ елчке наэтой кно пке вы зы вает-
ся про цедура для устано вки, а затем и для о тображ ения значения переменно й
GlobalStr. П о сл   е этого со здается друго й по ток, в ко торо м устанавливается и
о тображ ается его со бственно е значение этой переменно й. П о сле со здания вто-
рично го по тока первичны й вно вь вы зы ваетпро цедуру SetShowStr для о тобра-
ж ения переменно й GlobalStr.
   П о про буйте запустить это прило ж ение, сначала о бъ явив переменную
GlobalStr с по мо щ ью зарезервиро ванно го сл     о ва var, а затем – threadvar, и
про анализируйте различие врезультатах рабо ты .
Ли с т и н г 2. М одуль MAIN.PAS — дем он с т раци я хран ен и я локальн ы х п ере-
м ен н ы х п от оков
unit Main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
type
  TMainForm = class(TForm)
  Buttonl: TButton;
  procedure ButtonlClick(Sender: TObject);
  private
    { Закрытые объявления }
  public
    { Открытые объявления } end;
var
  MainForm: TMainForm;

Implementation

{ $R *.DFM}