Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка ТВП ЛР A5.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
611.84 Кб
Скачать

Завершение задачи

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

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

VOID ExitThread(DWORD dwExitCode);

Для принудительного завершения дочерней задачи родительская задача может использовать функцию TerminateThread, передав ей идентификатор завершаемой задачи и код завершения:

BOOL TerminateThread(

HANDLE hThread,

// идентификатор завершаемой задачи

DWORD dwExitCode);

// код завершения

Как родительская задача может получить код завершения дочерней задачи? Для этого она должна вызвать функцию GetExitCodeThread:

BOOL GetExitCodeThread(

HANDLE hThread,

// идентификатор завершаемой задачи

LPDWORD IpExitCode);

//адрес для приема кода завершения

Если задача, для которой вызвана функция GetExitCodeThread, все еще работает, вместо кода завершения возвращается значение STILL_ACTIVE.

Освобождение идентификатора задачи

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

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

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

Критические секции

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

Критическая секция создается как структура типа CRITICAL_SECTION:

CRITICAL_SECTION csWindowPaint;

Обычно эта структура располагается в области глобальных переменных, доступной всем запущенным задачам процесса. Так как каждый процесс работает в своем собственном адресном пространстве, вы не сможете передать адрес критической секции из одного процесса в другой. Именно поэтому критические секции нельзя использовать для синхронизации задач, созданных разными процессами.

В документации SDK отмечено, что структуру типа CRITICAL_SECTION нельзя перемещать или копировать.

Инициализация критической секции

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

CRITICAL_SECTION csWindowPaint;

InitializeCriticalSection(&csWindowPaint);

Функция InitializeCriticalSection имеет только один параметр (адрес структуры типа CRITICALJSECTION) и не возвращает никакого значения.