Лабораторная работа: Управление потоками в Windows

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Министерство сельского хозяйства

Казахский агротехнический университет имени С. Сейфуллина

Отчет

По дисциплине “Системное программирование”

Лабораторная работа

Управление потоками в Windows

Выполнил: Омурзаков Ильяс

Проверил(а): Боранбаев А.А.

г. Нур-Султан 2020 г.

Цель работы: изучить основы создания и управления потоками в ОС Windows.

Цели и задачи данной работы: Разработать многопоточное Win32-приложение, которое использует диалоговое окно для управления потоками процессов. Дизайн диалогового окна задается вариантом, преподавателем или самостоятельно. Для визуализации работы потоков использовать соответствующие элементы управления диалога, графику. Приложение должно содержать три потока. Предусмотреть вывод системной информации о потоках (например, полей CONTEXT, временны параметры и т.д.). В отчете привести диаграмму состояния потоков, копии окон.

Ход работы. Виды потоков, состояния потока

Поток является последовательностью команд, обрабатываемых процессором. В рамках одного процессора могут находиться один или несколько потоков. Процесс предоставляет ресурсы, поток - команды и данные для обработки. Процесс содержащий один поток называется однопоточным, в противном случае - многопоточным.

Многопоточная модель охватывает 2 категории потоков и их комбинацию:

потоки на уровне пользователя ULT (User Level Thread);

потоки на уровне ядра KLT (Kernel Level Thread);

комбинированная модель UKLT.

ULT управляются самим приложением. KLT управляется самим ядром через интерфейс прикладного программирования средств ядра ОС.

управление поток windows

Рисунок 1 - состояние потока.

Структура CONTEXT

У каждого потока собственный набор регистров процессора, называемый контекстом потока.

Эта структура с именем CONTEXT отражает состояние регистров процессора на момент последнего исполнения потока. Когда потоку выделяется процессорное время, система инициализирует регистры процессора содержимым контекста и, разумеется, регистр -- указатель команд идентифицирует адрес следующей машинной команды, необходимой для выполнения потока.

Кроме того, в контекст включается указатель стека, который определяет адрес стека» принадлежащего потоку. Получить сведения о текущем состоянии регистров процессора. можно с помощью функции:

BOOL GetThreadContext(HANDLE hThread, PCONTEXT pContext);

В программе(результатах) это выглядит так:

CONTEXT ct; ct.ContextFlags = (CONTEXT_FULL);

if(!GetThreadContext(hThread, &ct)) {return FALSE; }

Рисунок 2 - Контекст первого потока

Создание потока

Для создания потока используется функция CreateThread. В программе поток 1 создается следующим образом:

hThread1 = CreateThread(NULL, 0, First_Thread, hDlg, CREATE_SUSPENDED, &Id1);

Как и при работе с функцией CreateProcess, для многих параметров можно задавать значения по умолчанию (@ или NULL). Третий параметр не может иметь значение по умолчанию, ему всегда передается адрес функции потока. Четвертый параметр часто используется для организации взаимосвязи вызывающего потока с дочерним потоком. При каждом вызове функции CreateThread система создает объект ядра «поток» с начальным значением счетчика его пользователей, равным единице. Система выделяет память под стек потока из адресного пространства процесса. Новый поток выполняется в адресном пространстве того же процесса, что и родительский поток.

Относительный приоритет потока

Задать приоритет потока можно с помощью функции SetThreadPriority. Так это выглядит в программе: SetThreadPriority(hThread1, prir);

Эта функция меняет класс приоритета процесса, определяемого описателем hThread1, в соответствии со значением параметра prir. Этот параметр принимает одно из значений: IDLЕ_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, HIGH _PRIORITY_CLASS, REALTIME_PRIORITY_CLASS. При успешном выполнении функция возвращает TRUE; в ином случае -- FALSE. Поскольку SetPriorityClass принимает описатель процесса, то можно изменить приоритет любого процесса, выполняемого в системе, -- если его описатель известен и есть соответствующие права доступа.

Потоковая функция

Функция потока должна иметь следующий прототип:

DWORD WINAPI ThreadFunc(LPVOID IpvThreadParm) { DWORD dwResult = 0;

return(dwResult);}

Параметр IpvThreadParm функции потока идентичен параметру IpvThreadParm, первоначально передаваемому в CreateThread. Последняя лишь передает этот параметр той функции, с которой начинается выполнение создаваемого потока. Таким образом, данный параметр позволяет передавать функции потока какое-либо инициализирующее значение (просто 32-битное значение или 32-битный указатель на структуру данных с дополнительной информацией).

Пример функции потока, визуализирующий свою работу прогресс-баром, приведен ниже.

DWORD WINAPI TrackBarThread1(PVOID pvParam)

{

int count = 0;

int max_count = 1000;

SendMessage(GetDlgItem(hDlg, IDC_PROGRESS1), PBM_SETRANGE, 0, (LPARAM)MAKELONG(0, 1000));

SendMessage(GetDlgItem(hDlg, IDC_PROGRESS1), PBM_SETSTEP, (WPARAM) TRUE, (LPARAM) 1);

SendMessage(GetDlgItem(hDlg, IDC_PROGRESS1), PBM_SETPOS, 0,(LPARAM) 0);

while(count < max_count)

{

Sleep(10);

++count;

SendMessage(GetDlgItem(hDlg, IDC_PROGRESS1), PBM_STEPIT, 0, 0);

}

return 0;

}

Функции WinAPI для управления потоками

hThread2 = CreateThread(NULL, 0, Second_Thread, hDlg, CREATE_SUSPENDED, &Id2);

Назначение потоку относительного приоритета:

SetThreadPriority(hThread2, prir);

Возобновление потока: ResumeThread(hThread1);.

Приостановка потока: SuspendThread(hThread1);.

Получение времени создания, окончания потока и др.:

GetThreadTimes(hThread1,&pftCreationTime1, &pftExitTime1,&pftKernelTime1,&pftUserTime1);

Получение контекста потока:

GetThreadContext(hThread, &ct).

Завершение потока: ExitThread(0);.

Завершение потока извне: TerminateThread(hThread1, 0);.

Окончание потока

Существует несколько способов завершения потока:

1) функция потока возвращает управление

2) вызов функции ExitThread из потока

3) вызов функции TerminateThread

4)завершение процесса, содержащего данный поток

Время выполнения потока

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

GetThreadTimes(hThread[i],&creationTime,&exitTime,&kernelTime,&userTime);

// Дата и время создания процесса по Гринвичу

FileTimeToSystemTime(&creationTime, &stUTC);

// Конвертируем время создания процесса в местное время

SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal);

j+=sprintf(buf+j, "Время создания %d-го потока:%02d/%02d/%d %02d:%02d:%02d\r\n", i+1, stLocal.wDay,

stLocal.wMonth, stLocal.wYear, stLocal.wHour,

stLocal.wMinute, stLocal.wSecond);

// Дата и время завершения процесса по Гринвичу

FileTimeToSystemTime(&exitTime, &stUTC);

// Конвертируем время завершения процесса в местное время

SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal);

j+=sprintf(buf+j, "Время завершения %d-го потока: %02d/%02d/%d %02d:%02d:%02d\r\n\n", i+1, stLocal.wDay,

stLocal.wMonth, stLocal.wYear, stLocal.wHour,

stLocal.wMinute, stLocal.wSecond);

Результаты работы программного обеспечения

Рисунок 3 - Результат работы программы

Рисунок 4 - Информация о потоках

Выводы

Потоки -- это последовательность или цикл управления в процессе. Они обладают преимуществами по сравнению с созданием нового процесса, они позволяют создать программу, которая выполняет несколько задач одновременно. Множественные потоки менее требовательны к ресурсам, чем множественные процессы.

Функция CreateThread создает новый поток.

Когда поток завершается при выполнении потоковой функции, или при вызове функций ExitThread или TerminateThread, или при завершении процесса.

При выполнении данной лабораторной работы были выполнены все поставленные цели и задачи.

Источник: https://otherreferats.allbest.ru/download/1203891/