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;

Смотрите также

    Учебник по языку Pascal          Лабораторные работы по программированию          Справочник




Нет комментариев.



Оставить комментарий:
Ваше Имя:
Email:
Антибот: *  
Ваш комментарий: