Атрибуты потоков

advertisement
Атрибуты потоков
Атрибуты являются способом определить
поведение потока, отличное от поведения по
умолчанию. При создании потока с помощью
pthread_create() или при инициализации
переменной синхронизации может быть
определен собственный объект атрибутов.
Атрибуты определяются только во время
создания потока; они не могут быть изменены
в процессе использования.
Атрибуты потоков
Обычно вызываются три функции:
Инициализация
атрибутов
потока
pthread_attr_init()
создает
объект
pthread_attr_t tattr по умолчанию.
Изменение значений атрибутов (если значения по
умолчанию не подходят) - разнообразные функции
pthread_attr_*(), позволяющие установить
значения индивидуальных атрибутов для структуры
pthread_attr_t tattr.
Создание потока - вызов pthread_create() с
соответствующими значениями атрибутов в
структуре pthread_attr_t tattr.
Атрибуты потоков
Рассмотрим пример:
#include <pthread.h>
pthread_attr_t tattr; pthread_t tid;
void *start_routine; void arg;int ret;
/*атрибуты по умолчанию*/
ret = pthread_attr_init(&tattr);
/*вызов
функций
для
изменения
значений*/
ret=pthread_attr_*
(&tattr,
SOME_ATTRIBUTE_VALUE_PARAMETER);
/* создание потока */
ret
=
pthread_create(&tid,
&tattr,
Атрибуты потоков
Объект атрибутов является закрытым и не
может
быть
непосредственно
изменен
операциями присваивания. Как только атрибут
инициализируется и конфигурируется, это
доступен
всему
процессу.
Поэтому
рекомендуется конфигурировать все требуемые
спецификации состояния один раз на ранних
стадиях выполнения программы. При этом
соответствующий объект атрибутов может
использоваться везде, где это нужно.
Атрибуты потоков
Использование объектов атрибутов имеет два
основных преимущества:
Во-первых, это обеспечивает мобильность
кода. Даже в случае, когда поддерживаемые
атрибуты могут измениться в зависимости от
реализации, не нужно будет изменять вызовы
функций, которые создают объекты потоков,
потому что объект атрибутов скрыт от
интерфейса. Задача портирования облегчается,
потому что объекты атрибутов будут
инициализироваться
однажды
и
в
определенном месте.
Атрибуты потоков
Во-вторых,
упрощается
спецификация
состояний в приложении. Пусть в пределах
процесса существует несколько множеств
потоков, при этом каждое обеспечивает
отдельный сервис, и имеет свои собственные
требования к состоянию. В некоторый момент
на ранних стадиях приложения, можно
инициализировать объект атрибутов потока для
каждого множества. Все будущие вызовы
создания потока будут обращаться к объекту
атрибутов, инициализированному для этого
типа потока.
Атрибуты потоков
Объекты атрибутов требуют отдельного
внимания во время выхода из процесса. Когда
объект инициализируется, для него выделяется
память. Эта память должна быть возвращена
системе. Стандарт POSIX обеспечивает
функции для удаления объектов атрибутов.
Функция
pthread_attr_init()
используется, чтобы инициализировать объект
атрибутов значениями по умолчанию. Память
распределяется системой потоков во время
выполнения.
Атрибуты потоков
Пример вызова функции:
#include <pthread.h>
pthread_attr_t tattr;
int ret;
ret = pthread_attr_init(&tattr);
Функция
возвращает
0
после
успешного
завершения. Любое другое значение указывает, что
произошла ошибка. Код ошибки устанавливается в
переменной errno.
Значения по умолчанию для атрибутов (tattr)
приведены в таблице.
Атрибуты потоков
Атрибут
Значение по
умолчанию
detachstate PTHREAD_
CREATE_J
OINABLE
schedpolicy SCHED_OT
HER
Назначение
Управление
состоянием
потока
(присоединябельный/отсоединябельный)
Выбор политики диспетчеризации: SCHED_OTHER
(non-realtime), SCHED_RR
(realtime) или SCHED_FIFO
(realtime)
Атрибуты потоков
Атрибут
Значение по Назначение
умолчанию
schedparam 0
Приоритет при диспетчеризации, имеет смысл только
для
SCHED_RR
и
SCHED_FIFO
inheritsched PTHREAD_ Параметры диспетчеризаEXPLICIT_ ции задаются или наследуSCHED
ются от родительского
потока (PTHREAD_
INHERIT_SCHED)
Атрибуты потоков
Атрибут Значение по Назначение
умолчанию
scope
PTHREAD_ Это
единственное
SCOPE_SY поддерживаемое значение
STEM.
Атрибуты потоков
Функция pthread_attr_destroy() используется,
чтобы удалить память для атрибутов,
выделенную во время инициализации. Объект
атрибутов становится недействительным.
Пример вызова функции:
#include <pthread.h>
pthread_attr_t tattr;
int ret;
ret = pthread_attr_destroy(&tattr);
Функция возвращает 0 после успешного завершения
или любое другое значение в случае ошибки.
Отделение потока
Функция
pthread_detach()
является
альтернативой
pthread_join(),
чтобы
утилизировать область памяти для потока, который
был
создан
с
атрибутом
detachstate=
PTHREAD_CREATE_JOINABLE. Прототип :
int pthread_detach(thread_t tid);
Пример вызова функции:
#include <pthread.h>
pthread_t tid;
int ret;
ret = pthread_detach(tid);
Отделение потока
Функция pthread_detach() используется,
чтобы указать реализации, что выделенная
память для потока tid может быть
утилизирована, когда поток завершится. Если
tid не закончился, pthread_detach() не
вызывает его завершения.
pthread_detach() возвращает 0 при
успешном завершении. Любое другое значение
указывает, что произошла ошибка.
Состояние отделенного потока
Если
поток
создается
отделенным
(PTHREAD_CREATE_DETACHED), его PID и другие
ресурсы могут использоваться, как только он
завершится. Для этого можно вызвать перед его
созданием
функцию
pthread_attr_setdetachstate().
Если
поток
создается
неотделенным
(PTHREAD_CREATE_JOINABLE), предполагается,
что создающий поток будет ожидать его
завершения и выполнять pthread_join().
Независимо от типа потока, процесс не закончится,
пока не завершатся все потоки.
Состояние отделенного потока
pthread_attr_setdetachstate()
возвращает 0 после успешного завершения или
любое другое значение в случае ошибки.
Пример вызова для отсоединения потока:
#include <pthread.h>
pthread_attr_t tattr;
int ret;
ret =
pthread_attr_setdetachstate(&tattr
,PTHREAD_CREATE_DETACHED);
Состояние отделенного потока
Следующий код иллюстрирует, как можно создать
отделенный поток:
#include <pthread.h>
pthread_attr_t tattr, _t tid;
void *start_routine;
void arg; int ret;
ret = pthread_attr_init(&tattr);
ret
=
pthread_attr_setdetachstate
(&tattr,PTHREAD_CREATE_DETACHED);
ret = pthread_create(&tid, &tattr,
start_routine, arg);
Состояние отделенного потока
Функция pthread_attr_getdetachstate()
позволяет определить состояние при создании
потока, т.е. был ли он отделенным или
присоединяемым. Она возвращает 0 после
успешного завершения или любое другое значение в
случае ошибки. Пример вызова:
#include <pthread.h>
pthread_attr_t tattr;
int detachstate; int ret;
ret = pthread_attr_getdetachstate
(&tattr, &detachstate);
Ограничения потока
Поток может быть ограничен (имеет тип
PTHREAD_SCOPE_SYSTEM) или неограничен
(имеет тип PTHREAD_SCOPE_PROCESS). Оба
этих типа доступны только в пределах данного
процесса.
Функция
pthread_attr_setscope()
позволяет
создать потоки указанных типов.
pthread_attr_setscope() возвращает 0
после успешного завершения или любое
другое значение в случае ошибки.
Ограничения потока
Пример вызова функции:
#include <pthread.h>
pthread_attr_t attr, _t tid;
void start_routine;
void arg; int ret;
ret = pthread_attr_init (&tattr);
ret
=
pthread_attr_setscope
(&tattr, PTHREAD_SCOPE_SYSTEM);
ret = pthread_create (&tid,
&tattr, start_routine, arg);
Ограничения потока
Функция
pthread_attr_getscope()
используется для определения ограниченности
потока. Пример вызова:
#include <pthread.h>
pthread_attr_t tattr;
int scope; int ret;
ret = pthread_attr_getscope (&tattr,
&scope);
pthread_att_getscope() возвращает 0 после
успешного завершения или любое другое значение в
случае ошибки.
Дисциплина планирования
потока
Стандарт POSIX определяет несколько значений
атрибута планирования: SCHED_FIFO, SCHED_RR
(Round Robin), или SCHED_OTHER (метод
приложения). Дисциплины
SCHED_FIFO и
SCHED_RR
являются
необязательными,
и
поддерживаются только для потоков в режиме
реального времени.
Библиотека pthread поддерживает только
значение SCHED_OTHER. Попытка установить
другое значение приведет к возникновению ошибки
ENOSUP.
Дисциплина планирования
потока
Для ее установки используется функция:
#include <pthread.h>
pthread_attr_t tattr;
int ret;
ret
=
pthread_attr_setschedpolicy
(&tattr, SCHED_OTHER);
Парной
к
ней
является
функция
pthread_attr_getschedpolicy(), которая
возвращает константу, определяющую дисциплину
диспетчеризации.
Дисциплина планирования
потока
Функция pthread_attr_setinheritsched()
используется для наследования дисциплины
диспетчеризации из родительского потока.
Если
атрибут
inherit
=
PTHREAD_
INHERIT_SCHED (по умолчанию), то будет
использована дисциплина планирования родителя.
Если
используется
константа
PTHREAD_EXPLICIT_SCHED,
используются
атрибуты,
переданные
в
вызове
pthread_create().
Дисциплина планирования
потока
Функция возвращает 0 при успешном
завершении, и любое другое значение в случае
ошибки. Пример вызова этой функции:
#include <pthread.h>
pthread_attr_t tattr;
int ret;
ret=pthread_attr_setinheritsched
(&tattr, PTHREAD_EXPLICIT_SCHED);
Дисциплина планирования
потока
Функцию
pthread_attr_getinheritsched
(pthread_attr_t *tattr, int *inherit)
можно использовать для получения информации о
дисциплине планирования текущего потока.
Параметры
диспетчеризации
определены
в
структуре sched_param; поддерживается только
приоритет
sched_param.sched_priority.
Этот приоритет задается целым числом, при этом
чем выше значение, тем выше приоритет потока при
планировании. Создаваемые потоки получают этот
приоритет.
Дисциплина планирования
потока
Функция
pthread_attr_setschedparam()
используется, чтобы установить значения в этой
структуре. При успешном завершении она
возвращает 0. Пример использования:
#include <pthread.h>
pthread_attr_t tattr; int newprio;
sched_param param; newprio = 20;
param.sched_priority = newprio;
ret = pthread_attr_setschedparam
(&tattr, &param);
Дисциплина планирования
потока
Функция
pthread_attr_getschedparam
(pthread_attr_t *tattr, const
struct sched_param *param)
используется для получения приоритета
текущего потока.
Download