Потоковые атрибуты — это механизм настройки поведения отдельных потоков. Вспомните, что функция pthread_create()
принимает аргумент, являющийся указателем на объект атрибутов потока. Если этот указатель равен NULL
, поток конфигурируется на основании стандартных атрибутов.
Для задания собственных атрибутов потока выполните следующие действия.
1. Создайте объект типа pthread_attr_t
.
2. Вызовите функцию pthread_attr_init()
, передав ей указатель на объект. Эта функция присваивает неинициализированным атрибутам стандартные значения.
3. Запишите в объект требуемые значения атрибутов.
4. Передайте указатель на объект в функцию pthread_create()
.
5. Вызовите функцию pthread_attr_destroy()
, чтобы удалить объект из памяти. Сама переменная pthread_attr_t
не удаляется; ее можно проинициализировать повторно с помощью функции pthread_attr_init()
.
Один и тот же объект может быть использован для запуска нескольких потоков. Нет необходимости хранить объект после того, как поток был создан.
Для большинства Linux-приложений интерес представляет один-единственный атрибут (остальные используются в приложениях реального времени): статус отсоединения потока . Поток может быть создан как ожидаемый (по умолчанию) или отсоединенный . Ожидаемый поток, подобно процессу, после своего завершения не удаляется автоматически операционной системой Linux. Код его завершения хранится где-то в системе (как у процесса-зомби), пока какой-нибудь другой поток не вызовет функцию pthread_join()
, чтобы запросить это значение. Только тогда ресурсы потока считаются освобожденными. С другой стороны, отсоединенный поток, завершившись, сразу уничтожается. Другие потоки не могут вызвать по отношению к нему функцию pthread_join()
или получить возвращаемое им значение.
Чтобы задать статус отсоединения потока, воспользуйтесь функцией pthread_attr_setdetachstate()
. Первый ее аргумент — это указатель на объект атрибутов потока, второй — требуемый статус. Ожидаемые потоки создаются по умолчанию, поэтому в качестве второго аргумента имеет смысл указывать только значение PTHREAD_CREATE_DETACHED
.
Программа, представленная в листинге 4.5, создает отсоединенный поток, устанавливая соответствующим образом атрибуты потока.
Листинг 4.5. ( detached.c ) Шаблон программы, создающей отсоединенный поток
#include
void* thread_function(void* thread_arg) {
/* Тело потоковой функции... */
}
int main() {
pthread_attr_t attr;
pthread_t thread;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&thread, &attr, &thread_function, NULL);
pthread_attr_destroy(&attr);
/* Тело основной программы... */
/* Дожидаться завершения второго потока нет необходимости. */
return 0;
}
Даже если поток был создан ожидаемым, его позднее можно сделать отсоединенным. Для этого нужно вызвать функцию pthread_detach()
. Обратное преобразование невозможно.
Обычно поток завершается при выходе из потоковой функции или вследствие вызова функции pthread_exit()
. Но существует возможность запросить из одного потока уничтожение другого. Это называется отменой, или принудительным завершением, потока.
Чтобы отменить поток, вызовите функцию pthread_cancel()
, передав ей идентификатор требуемого потока. Далее можно дождаться завершения потока. Вообще-то, это обязательно нужно делать с целью освобождения ресурсов, если только поток не является отсоединенным. Отмененный поток возвращает специальное значение PTHREAD_CANCELED
.
Во многих случаях поток выполняет код, который нельзя просто взять и прервать. Например, поток может выделить какие-то ресурсы, поработать с ними, а затем удалить. Если отмена потока произойдет где-то посередине, освободить занятые ресурсы станет невозможно, вследствие чего они окажутся потерянными для системы. Чтобы учесть эту ситуацию, поток должен решить, где и когда он может быть отменен.
С точки зрения возможности отмены поток находится в одном из трех состояний.
■ Асинхронно отменяемый . Такой поток можно отменить в любой точке его выполнения.
■ Синхронно отменяемый . Поток можно отменить, но не везде. Запрос на отмену помещается в очередь, и поток отменяется только по достижении определенной точки.
■ Неотменяемый . Попытки отменить поток игнорируются. Первоначально поток является синхронно отменяемым.
Читать дальше