BeginThread, функция
Синтаксис
function BeginThread(SecurityAttributes: Pointer; StackSize: LongWord;
   ThreadFunc: TThreadTunc; Parameter: Pointer; CreationFlags: LongWord; 
   var Threadld:  LongWord):  Integer;
 
Описание
  Функция BeginThread вызывается для запуска потока в многопоточ-ном приложении 
  и обращается к функции Windows API CreateThread. которая начинает новый поток 
  и, в свою очередь, вызывает функця потока (ThreadFunc) в контексте нового потока. 
  Когда функция поток заканчивает работу, поток завершается. За дополнительной 
  информ цией об атрибутах безопасности и флагах обратитесь к документации Windows 
  API по функции CreateThread. 
   
  BeginThread возвращает дескриптор нового потока или ноль, если Windows не создаст 
  поток. BeginThread - это настоящая функция.
 
Ошибки
 
 
Советы и приемы
  
    -  Следует использовать функцию BeginThread вместо функции CreateThread 
      Windows API, т.к. BeginThread выставляет глобальную переменную IsMuItiTread 
      в истину. BeginThread также определяет параметры ThreadFunc и ThreadID в 
      стиле языка Паскаль.
    
 - Функция потока должна перехватывать и обрабатывать все исключительные 
      ситуации. Если функция потока вызывает исключительную ситуацию, которую 
      не может обработать, ее перехватывает BeginThread и прерывает программу.
 
     -  Как и для любого другого ресурса, следует вызвать CloseHandle после окончания 
      работы потока, чтобы Windows освободил все связанные с ним ресурсы. Если 
      вы создадите поток в приостановленном состоянии и затем закроете его, ни 
      разу не запустив, в Delphi произойдет небольшая утечка памяти. Чтобы предотвратит: 
      утечку, всегда запускайте поток до того, как его закроете.
  
  
 
Пример
В следующем примере показан фоновый поток, который вычисляв множество Мандельброта и рисует его 
изображение в растре. Фоновый поток уведомляет основной поток программы о том, что формирование
изображения закончено, и оно может быть выведено на экран. 
В фоновом потоке используется свойство Scanline, т. к. это обеспечивает быстрый и удобный доступ к 
данным растра без привлечения Windows АРI. Если потоку требуются функции Windows GDI, 
следует использовать метод TThread Synchronize из модуля Classes.
const   // Фоновый поток посылает это сообщение основному. 
  Wm_Finished = Wm_User; 
type
  TThreadInfo = class;
  TWmFinished = packed record
     Msg: Cardinal;
     Aborted: Boolean;
     Bitmap: TBitmap;
     Rasult: LongInt;
  end;
  // Каждому потоку передается объект Threadlnfo. Обьект создает
  // растровое изображение,  в котором создается множество Мандельбрста
  // и флаг,  который поток периодически проверяет, чтобы определить
  // необходимость заранее прервать свою работу.
  TThreadlnfo = class
  private
    fBitmap:  TBitmap;
    fAborted: Boolean;
  Public
    constructor Create(Width, Height:	Integer);
    destructor Destroy; override;
    procedure Abort;
    property Bitmap: TBitmap read fBitmap;
    property Aborted: Boolean read fAborted;
  end;
    // Число итераций устанавливаем равным 360, чтобы было легче
    // преобразовать количество итераций в значение Hue (цветовое
    // смещение) в цветовой схеме HSV.
const
    Maxlterations = 360;
// Смотрите пример для процедуры Exit, чтобы найти функцию
// Computelterations.
// Эти начальные точки смотрятся неплохо. Вы можете их изменить,
// если хотите увидеть что-нибудь другое.
const
  XOffset = -0.03;
  YOffset = 0.78;
  Zoom = 450000.0;
  Background = clBlack;
// Растр использует 24-разрядный формат пикселов, так что
// каждый пиксел зачинает три байта. Массив TRgb облегчает доступ
// к красной, зеленой и синей компонентам цвета строки изображения.
type
  TRgb = array[0..2] of Byte;
  PRgb = ^TRgb;
function MandelbrotThread(Param: Pointer): Integer;
var
  Info: TThreadlnfo;
  R, C: Integer;			// Положение в растре.
  Color: TColor;	 		 // Цвет пикселя.
  Count: Integer;		// Количество итераций.
  X, Y: Double;			// Положение на воображаемой
								// плоскости.
  Xlncrement, YIncrement: Double; 	// Шаг изменения координат X и Y.
  Scanline: PRgb;								// Доступ к изображению выполняется
														// построчно.
begin
  Result :=0;
  Info := TThreadlnfo(Param);
  Xlncrement := Info.Bitmap.Width / Zoom;
  YIncrement := Info.Bitmap.Height / Zoom;
  Y := YOffset;
  for R := 0 to Info.Bitmap.Height-1 do
  begin
     X := XOffset;
    Scanline := Info.Bitmap.ScanLine[R];
    for C := 0 to Info.Bitmap.Width-1 do
    begin
       Count := CoroputeIterations(X, Y); // Смотрите процедуру Exit.
       X := X + Xlncrement;
       // Преобразуем значение максимального числа итераций в цвет
       // фона,а другие значения количества итераций - в различные
       // цвета путем использования count в качестве значения компо-
       // ненты цветового смещения в цветовой схеме.
       if Count = Maxlterations then
          Color := Background
       else
          Color := HSV(Count, 255, 255);
       Scanline[0] := GetBValue(Color);
 	    Scanline[1] := GetGValue(Color);
		Scanline[2] := GetRValue(Color);
		Inc(Scanline); 
    end;
    Y := Y + YIncrement;
    if Info.Aborted then
    begin
       PostMessage(Form1.Handle, Wm_Finished, 1, LParam(Param));
       Exit; 
    end;
  end;
  // Сообщаем основному потоку, что фоновый поток завершил свою
  // работу, Передаем объект Threadlrifo в качестве параметра // сообщения.
  PostMessage(Form1.Handle, Wm_Finished, 0, LParam(Param));
end;
// Когда фоновый поток завершается, рисуем изображение и освобождаем
// объект Tiireadlnfo.
procedure TForm1.WmFinished(var Msg: TWmFinished);
begin
  if not Msg.Info.Aborted then
    Image1.Picture.Bitmap := Msg.Info.Bitmap;
  FreeAndNil(Msg.Info);
  CloseHandle(Thread);
  Thread  := 0;
end;
// Создаем новый поток для вычисления и формирования множества
// Мандельброта, Info - это запись типа TThreadlnfo, которая
// является закрытым полем класса TForm1. Thread - это THandle,
// тоже закрытое поле.
procedure TForm1.StartThread;
var
  Id:  Cardinal;
begin
   Info := TThreadInfo.Create(lmage1.Width,  Image1.Height);
   Thread := BeginThread(nil, 0, @HandeAbrotThread, Info,  0, Id);
end;
// Когда форма закрывается, она прерывает поток. Возможно,  что сообщение
// Wm_Finished придет после разрушения формы,  но это не является
// большой проблемой, т.к. Windows уничтожит поток при завершении
// программы.
procedure TForm1.FormClosed(Sender:  TObject);
begin
  if Info <> nil then
    Info.Abort;
end;
 
Смотрите также
 
 
 Нет комментариев. 
  
 
Оставить комментарий:
 |   
 |