Лекция 4

· Поток(thread) определяет последовательность исполнения кода в процессе.

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

Примеры: проверка правописания в текстовом редакторе; выполнение расчетов на нескольких процессорах; моделирование поведения систем, состоящих из независимых элементов.

Для порождения нового потока используется функция

function CreateThread (lpThreadAttributes: Pointer;

dwStackSize: DWORD;

lpStartAddress: TFNThreadStartRoutine;

lpParameter: Pointer;

dwCreationFlags: DWORD;

var lpThreadId: DWORD

):THandle;

Функция создает объект ядра - поток и все его структуры, создает стек потока и запускает его на выполнение (не всегда).При удачном создании потока функция вернет его описатель, иначе 0. Код ошибки можно узнать, вызвав функцию function GetLastError.

lpThreadAttributes - атрибуты защиты для потока.

dwStackSize - определяет часть адресного пространства, отводимого под стек. Если вы обнулили этот параметр, то размер стека будет найден в коде приложения (компоновщик позволяет управлять размером стека для приложения). По умолчанию 1 Мб.

lpStartAddress - определяет адрес стартовой функции потока. Функция должна иметь вид function …(lpParameter:pointer):integer; Параметр lpParameter идентичен параметру lpParameter передаваемому в CreateThread. По сути функция создания потока передает этот параметр по эстафете стартовой функции потока. В данной функции должен содержаться весь код потока, так как по ее завершению, поток будет завершен.

dwCreationFlags - определяет дополнительные флаги, управляющие созданием потока.0-поток начинает выполняться немедленно, CREATE_SUSPENDED - поток приостанавливает свое выполнение до дальнейших указаний.

lpThreadId - возвращаемый идентификатор потока

Пример:

var

hObjThread:THandle;

function StartThread(Param:pointer):integer;

begin

ShowMessage('Поток создан'+#13+

'Псевдоописатель $'+IntToHex(GetCurrentThread,32)+#13+

'ID потока $'+IntToHex(GetCurrentThreadId,32));

// что то делаем

end;

procedure TForm1.Button1Click(Sender: TObject);

var ThreadId: DWORD;

begin

hObjThread:=CreateThread(nil,0, @StartThread, nil, 0, ThreadId);

if hObjThread=0 then

raise Exception.Create(SysErrorMessage(GetLastError));

LabelThreadHandle.Caption:='Описатель потока $'+IntToHex(hObjThread,32);

LabelThreadID.Caption:='ID потока $'+IntToHex(integer(ThreadId),32);

end;

Корректнее использовать BeginThread из библиотеки Delphi, которая устанавливает фрейм исключения, разрешая ОС обработать исключения, которые возникают внутри стартовой функции потока.

Несколько полезных функций, относящихся к потоку.

function GetThreadTimes (hThread: THandle; var lpCreationTime, lpExitTime, lpKernelTime, lpUserTime: TFileTime): BOOL; - возвращает время, затраченное на выполнение потока. Параметры: lpCreationTime - время создания потока, lpExitTime - время завершения потока, lpKernelTime - время затраченное на выполнение кода ядра, lpUserTime - время затраченное на выполнение кода потока. (Только в Windows NT)

Завершить поток можно тремя способами

1. потоков вызывает функцию procedure ExitThread (dwExitCode: DWORD); dwExitCode - код возврата.

2. Поток процесса вызывает function TerminateThread (hThread: THandle; dwExitCode: DWORD): BOOL;

3. Процесс, содержащий данный поток завершается.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: