Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Хьюз Камерон. Параллельное и распределенное программирование на С++ - royallib.ru.doc
Скачиваний:
119
Добавлен:
11.03.2016
Размер:
1.97 Mб
Скачать

Завершение потоков

Выполнение потока может быть прервано по разным причинам:

• в результате выхода из процесса с возвращаемым им статусом завершения (или без него);

• в результате собственного завершения и предоставления статуса завершения;

• в результате аннулирования другим потоком в том же адресном пространстве.

Завершаясь, функция присоединения потока pthread_join() возвращает вызывающему потоку статус завершения, передаваемый функции pthread_exit(), которая была вызвана завершающимся потоком. Если завершающийся поток не обращался к функции pthread_exit (), то в качестве статуса завершения будет использовано значение, возвращаемое этой функцией, если оно существует; в противном случае статус завершения равен значению NULL. 9 Воз можна ситуация, когда одному потоку необходимо завершить другой поток в том же процессе. Например, приложение может иметь поток, который контролирует работу других потоков. Если окажется, что некоторый поток «плохо себя ведет», или больше не нужен, то ради экономии системных ресурсов, возможно, его нужно завершить. Завершающийся поток может окончиться немедленно или отложить завершение до тех пор, пока не достигнет в своем выполнении некоторой логической точки. При этом вполне вероятно, что такой поток (прежде чем завершиться) должен выполнить некоторые действия очистительно-восстановительного характера. Поток имеет также возможность отказаться от завершения.

Для завершения вызывающего потока используется функция pthread_exit () Значение value_ptr передается потоку, который вызывает функцию pthread_join() для этого потока. Еще не выполненные процедуры, связанные с «уборкой», будут выполнены вместе с деструкторами, предусмотренными для потоковых данных. Никакие ресурсы, используемые потоками, при этом не освобождаются.

Синопсис

#include <pthread.h>

int pthread_exit(void *value_ptr);

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

Для отмены выполнения некоторого потока по инициативе потока из того же адресного пространства используется функция pthread__cancel (). Отменяемый поток задается параметром thread.

Синопсис

#include <pthread.h>

int pthread_cancel(pthread_t thread);

Обращение к функции pthread_cancel () представляет собой запрос аннулировать поток. Этот запрос может быть удовлетворен немедленно, с отсрочкой или проигнорирован. Когда произойдет аннулирование (и произойдет ли оно вообще), зависит от типа аннулирования и состояния потока, подлежащего этой кардинальной операции. Для удовлетворения запроса на отмену потока предусмотрен процесс аннулирования, который происходит асинхронно (т.е. не совпадает по времени) по отношению к выходу из функции pthread_cancel() и ее возврату в вызывающий поток. Если потоку нужно выполнить «уборочные» задачи, они обязательно выполняются. После выполнения последней такой задачи-обработчика вызываются деструкторы потоковых объектов, если таковые предусмотрены, и только после этого поток завершается. В этом и состоит процесс аннулирования потока. При успешном выполнении функция pthread_cancel () возвращает число 0 , в противном случае — код ошибки. Эта функция не выполнится успешно, если параметр thread не соответствует ни одному из существующих потоков.

Некоторые потоки могут потребовать принять меры безопасности против преждевременного их аннулирования. Внесение в потоковую функцию средств безопасности может предотвратить возникновение некоторых нежелательных ситуаций. Потоки разделяют общие данные, и (в зависимости от используемой потоковой модели) один поток может обрабатывать данные, которые должны быть переданы другому потоку для последующей обработки. Пока поток обрабатывает данные, он является их единственным обладателем благодаря блокированию мьютекса, связанного с этими данными. Если поток, имеющий заблокированный мьютекс, аннулируется до его освобождения, возникает взаимоблокировка. Для того чтобы снова использовать данные, их следует привести в определенное состояние. Если поток отменяется до освобождения мьютекса, могут возникнуть нежелательные условия. Другими словами, в зависимости от типа обработки, которую выполняет поток, его аннулирование должно происходить тогда, когда это безопасно. Об опасных и безопасных периодах «знает» только сам поток, и поэтому только он может предотвратить свое аннулирование в опасные периоды. Следовательно, круг потоков, которые можно аннулировать, должен быть ограничен потоками, которые не относятся к числу «жизненно важных» или которые не имеют блокировок ресурсов. Кроме того, аннулирование может быть отсрочено до тех пор, пока не будут выполнены «жизненно важные» действия.

Состояние готовности к аннулированию (cancelability state) описывает условия, при которых поток может (или не может) быть аннулирован. Тип аннулирования (cancelabilty type) потока определяет способность потока продолжать выполнение после получения запросов на аннулирование. Поток может отреагировать на аннулирующий запрос немедленно или отложить аннулирование до определенной (более поздней) точки в его выполнении. Состояние готовности к аннулированию и тип аннулирования устанавливаются динамически самим потоком.

Для определения состояния готовности к аннулированию и типа аннулирования вызывающего потока используются функции p thread_setcancelstate() pthread_setcanceltype(). Функция pthread_setcancelstate() устанавливает вызывающий поток в состояние, заданное параметром state, и возвращает предыдущее состояние в параметре oldstate.

Синопсис

#include <pthread.h>

int pthread_setcancelstate(int state, int *oldstate);

int pthread_setcanceltype(int type, int *oldtype);

Параметры state и oldstate могут принимать такие значения:

PTHREAD_CANCEL_DISABLE

PTHREAD_CANCEL_ENABLE

Значение PTHREAD_CANCEL_DISABLE определяет состояние, в котором поток будет игнорировать запрос на аннулирование, а значение PTHREAD_CANCEL_ENABLE - состояние, в котором поток «согласится» выполнить соответствующий запрос (это состояние по умолчанию устанавливается для каждого нового потока). При успешном выполнении функция возвращает число 0 , в противном случае — код ошибки. Функция pthread_setcancelstate() не может выполниться успешно, если переданное

значение параметра state окажется недействительным. Функция pthread_setcanceltype () устанавливает для вызывающего потока тип аннулирования, заданный параметром type, и возвращает предыдущее значение типа в параметре oldtype. Параметры type и oldtype могут принимать такие значения:

PTHREAD_CANCEL_DEFFERED

PTHREAD_ASYNCHRONOUS

Значение PTHREAD_CANCEL_DEFFERED определяет тип аннулирования, при котором поток откладывает завершение до тех пор, пока он не достигнет точки, в котором его аннулирование возможно (этот тип по умолчанию устанавливается для каждого нового потока). Значение PTHREAD_CANCEL_ASYNCHRONOUS определяет тип аннулирования, при котором поток завершается немедленно. При успешном выполнении функция возвращает число 0 , в противном случае— код ошибки. Функция pthread_setcanceltype() не может выполниться успешно, если переданное ей значение параметра type окажется недействительным.

Функции pthread_setcancelstate() и pthread_setcanceltype() используются вместе для установки отношения вызывающего потока к потенциальному запросу на аннулирование. Возможные комбинации значений состояния и типа аннулирования перечислены и описаны в табл. 4 .5.

Таблица 4.5. Комбинации значений состояния и типа аннулирования

Состояние   Тип   Описание

PTHREAD_CANCEL_ENABLE (PTHREAD_CANCEL_DEFERRED) Отсроченное аннулирование. Эти состояние и тип аннулирования потока устанавливаются по умолчанию. Аннулирование потока происходит, когда он достигает соответствующей точки в своем выполнении или когда программист определяет точку аннулирования с помощью функции pthread_testcancel()

PTHREAD_CANCEL_ENABLE (PTHREAD_CANCEL_ASYNCHRONOUS)

Асинхронное аннулирование. Аннулирование потока происходит немедленно

PTHREAD_CANCEL_DISABLE (любое)

Аннулирование запрещено. Оно вообще не выполняется