Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка к лабораторным работам (рус).doc
Скачиваний:
3
Добавлен:
15.11.2018
Размер:
353.79 Кб
Скачать

1.3.5. Переключение потоков

Следующая функция позволяет подключить к процессору следующий планируемый поток (конечно, если он есть):

BOOL SwitchToThread();

Когда вызывается данная функция, система проверяет, есть ли поток, которому не хватает процессорного времени. Если нет, SwitchToThread немедленно возвращает управление (результат функции в этом случае - FALSE), а если да, планировщик отдает ему дополнительный квант времени. По истечению этого кванта времени планировщик возвращается в нормальный режим.

1.3.6. Определение периодов выполнения потоков

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

int Start = GetTickCount();

// Алгоритм

int Res = GetTickCount() – Start;

Данный метод основан на допущении, что выполняемый поток не будет прерван. В реальности, это условие невыполнимо. Поэтому, существует специальная функция, определяющая временные характеристики потока:

BOOL GetThreadTimes(

HANDLE hThread,

LPFILETIME lpCreationTime ,

LPFILETIME lpExitTime ,

LPFILETIME lpKernelTime ,

LPFILETIME lpUserTime

);

lpCreationTime - абсолютная величина, выраженная в интервалах по 100нс. Отсчитывается с полуночи 1 января 1601 года по Гринвичу до момента создания потока.

LpExitTime - абсолютная величина , выраженная в интервалах по 100нс. Отсчитывается с полуночи 1 января 1601 года по Гринвичу до момента завершения потока. Если поток все еще выполняется, этот показатель имеет неопределенное значение (либо устанавливается в 0).

LpKernelTime - абсолютная величина , выраженная в интервалах по 100нс. Сообщает время, затраченное потоком на выполнение кода операционной системы.

LpUserTime - абсолютная величина , выраженная в интервалах по 100нс. Сообщает время, затраченное потоком на выполнение кода приложения.

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

FILETIME KernelStart, KernerEnd;

FILETIME UserStart, UserEnd;

FILETIME t;

GetThreadTimes(GetCurrentThread(), &t, &t, &KernelStart,&UserStart);

// ввыполняем алгоритм

GetThreadTimes(GetCurrentThread(), &t, &t, &KernelEnd,&UserEnd);

int TimeKernel = KernelEnd.dwLowDateTime-KernelEnd.dwLowDateTime;

int UserKernel = UserEnd.dwLowDateTime-UserEnd.dwLowDateTime;

// при условии, что время помещается в 32 бита!

Существует аналогичная функции GetThreadTimes для определения суммарного времени, затрачиваемого на выполнения всех потоков процесса.

Существуют две специальные функции для высокоточного измерения интервалов, применение которых основано на допущении, что они применяются для быстро выполняемых участков кода, которые не вытесняются:

BOOL QueryPerformanceFrequency( LARGE_INTEGER *lpFrequency );

BOOL QueryPerformanceCounter( LARGE_INTEGER *lpPerformanceCount);

Вот пример применения этих функций:

LARGE_INTEGER Fraq;

LARGE_INTEGER St, En;

QueryPerformanceFrequency(&Fraq);

QueryPerformanceCounter(&St);

// ввыполняем алгоритм

QueryPerformanceCounter(&En);

int Rez = ( (En.QuadPart – St.QuadPart) * 1000 ) / Fraq.QuadPart;

//результат в миллисекундах