Provided by: manpages-ru-dev_4.23.1-1_all 

ИМЯ
pthread_getattr_np - возвращает атрибуты созданной нити
LIBRARY
POSIX threads library (libpthread, -lpthread)
СИНТАКСИС
#define _GNU_SOURCE /* Смотрите feature_test_macros(7) */
#include <pthread.h>
int pthread_getattr_np(pthread_t thread, pthread_attr_t *attr);
ОПИСАНИЕ
Функция pthread_getattr_np() инициализирует объект атрибутов нити, на который указывает attr, так, чтобы
он содержал актуальные значения атрибутов выполняющейся нити thread.
Возвращаемые значения атрибутов могут отличаться от соответствующих значений атрибутов переданных в
объекте attr, который использовался при создании нити с помощью pthread_create(3). В частности, могут
отличаться следующие атрибуты:
• состояние отсоединения, так как присоединяемая нить могла сама отсоединиться после создания;
• размер стека, так как реализация нитей могла выронить значение по уместной границе.
• размер защиты, так как реализация нитей могла округлить значение в большую сторону до кратного размера
страницы, или проигнорировать (т. е., посчитать за 0), если приложение само выделяет себе стек.
Кроме этого, если атрибут адреса стека не был указан в объекте атрибутов нити при создании нити, то
возвращаемый объект атрибутов нити будет содержать актуальный адрес стека, который был выбран реализацией
для нити.
Когда объект атрибутов нити, возвращаемый pthread_getattr_np(), больше не требуется, то он должен быть
удалён с помощью pthread_attr_destroy(3).
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении функция возвращает 0; при ошибке возвращается ненулевой номер ошибки.
ОШИБКИ
ENOMEM Недостаточно памяти.
Также, если thread указывает на главную нить, то pthread_getattr_np() может завершиться с ошибкой из-за
ошибок различных используемых вызовов: fopen(3), если невозможно открыть /proc/self/maps; getrlimit(2),
если не поддерживается ограничение ресурса RLIMIT_STACK.
АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).
┌─────────────────────────────────────────────────────────────────────┬──────────────────────┬──────────┐
│ Интерфейс │ Атрибут │ Значение │
├─────────────────────────────────────────────────────────────────────┼──────────────────────┼──────────┤
│ pthread_getattr_np() │ Безвредность в нитях │ MT-Safe │
└─────────────────────────────────────────────────────────────────────┴──────────────────────┴──────────┘
СТАНДАРТЫ
GNU; hence the suffix "_np" (nonportable) in the name.
ИСТОРИЯ
glibc 2.2.3.
ПРИМЕРЫ
В программе, показанной далее, демонстрируется использование pthread_getattr_np(). Программа создаёт
нить, которая, затем, использует pthread_getattr_np() для получения и показа своих атрибутов размера
защиты, адреса стека и размера стека. Аргументами командной строки можно изменить эти атрибуты. Работа
программы показана далее.
В этом запуске на системе x86-32 нить создаётся со значениями атрибутов по умолчанию:
$ ulimit -s # Без ограничения стека ==>
# размер стека по умолчанию 2 МБ
unlimited
$ ./a.out
Атрибуты созданной нити:
Размер защиты = 4096 байт
Адрес стека = 0x40196000 (EOS = 0x40397000)
Размер стека = 0x201000 (2101248) байт
В этом запуске мы видим, что при задании размера защиты его значение округляется до значение следующего
кратного размера системной страницы (4096 байт на x86-32):
$ ./a.out -g 4097
Thread attributes object after initializations:
Guard size = 4097 bytes
Stack address = (nil)
Stack size = 0x0 (0) bytes
Attributes of created thread:
Guard size = 8192 bytes
Stack address = 0x40196000 (EOS = 0x40397000)
Stack size = 0x201000 (2101248) bytes
В этом запуске программа вручную выделяет стек для нити. В этом случае атрибут размера защиты
игнорируется.
$ ./a.out -g 4096 -s 0x8000 -a
Allocated thread stack at 0x804d000
Thread attributes object after initializations:
Guard size = 4096 bytes
Stack address = 0x804d000 (EOS = 0x8055000)
Stack size = 0x8000 (32768) bytes
Attributes of created thread:
Guard size = 0 bytes
Stack address = 0x804d000 (EOS = 0x8055000)
Stack size = 0x8000 (32768) bytes
Исходный код программы
#define _GNU_SOURCE /* To get pthread_getattr_np() declaration */
#include <err.h>
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void
display_stack_related_attributes(pthread_attr_t *attr, char *prefix)
{
int s;
size_t stack_size, guard_size;
void *stack_addr;
s = pthread_attr_getguardsize(attr, &guard_size);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_attr_getguardsize");
printf("%sGuard size = %zu bytes\n", prefix, guard_size);
s = pthread_attr_getstack(attr, &stack_addr, &stack_size);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_attr_getstack");
printf("%sStack address = %p", prefix, stack_addr);
if (stack_size > 0)
printf(" (EOS = %p)", (char *) stack_addr + stack_size);
printf("\n");
printf("%sStack size = %#zx (%zu) bytes\n",
prefix, stack_size, stack_size);
}
static void
display_thread_attributes(pthread_t thread, char *prefix)
{
int s;
pthread_attr_t attr;
s = pthread_getattr_np(thread, &attr);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_getattr_np");
display_stack_related_attributes(&attr, prefix);
s = pthread_attr_destroy(&attr);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_attr_destroy");
}
static void * /* Start function for thread we create */
thread_start(void *arg)
{
printf("Attributes of created thread:\n");
display_thread_attributes(pthread_self(), "\t");
exit(EXIT_SUCCESS); /* Terminate all threads */
}
static void
usage(char *pname, char *msg)
{
if (msg != NULL)
fputs(msg, stderr);
fprintf(stderr, "Usage: %s [-s stack-size [-a]]"
" [-g guard-size]\n", pname);
fprintf(stderr, "\t\t-a means program should allocate stack\n");
exit(EXIT_FAILURE);
}
static pthread_attr_t * /* Get thread attributes from command line */
get_thread_attributes_from_cl(int argc, char *argv[],
pthread_attr_t *attrp)
{
int s, opt, allocate_stack;
size_t stack_size, guard_size;
void *stack_addr;
pthread_attr_t *ret_attrp = NULL; /* Set to attrp if we initialize
a thread attributes object */
allocate_stack = 0;
stack_size = -1;
guard_size = -1;
while ((opt = getopt(argc, argv, "ag:s:")) != -1) {
switch (opt) {
case 'a': allocate_stack = 1; break;
case 'g': guard_size = strtoul(optarg, NULL, 0); break;
case 's': stack_size = strtoul(optarg, NULL, 0); break;
default: usage(argv[0], NULL);
}
}
if (allocate_stack && stack_size == -1)
usage(argv[0], "Specifying -a without -s makes no sense\n");
if (argc > optind)
usage(argv[0], "Extraneous command-line arguments\n");
if (stack_size != -1 || guard_size > 0) {
ret_attrp = attrp;
s = pthread_attr_init(attrp);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_attr_init");
}
if (stack_size != -1) {
if (!allocate_stack) {
s = pthread_attr_setstacksize(attrp, stack_size);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_attr_setstacksize");
} else {
s = posix_memalign(&stack_addr, sysconf(_SC_PAGESIZE),
stack_size);
if (s != 0)
errc(EXIT_FAILURE, s, "posix_memalign");
printf("Allocated thread stack at %p\n\n", stack_addr);
s = pthread_attr_setstack(attrp, stack_addr, stack_size);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_attr_setstacksize");
}
}
if (guard_size != -1) {
s = pthread_attr_setguardsize(attrp, guard_size);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_attr_setstacksize");
}
return ret_attrp;
}
int
main(int argc, char *argv[])
{
int s;
pthread_t thr;
pthread_attr_t attr;
pthread_attr_t *attrp = NULL; /* Set to &attr if we initialize
a thread attributes object */
attrp = get_thread_attributes_from_cl(argc, argv, &attr);
if (attrp != NULL) {
printf("Thread attributes object after initializations:\n");
display_stack_related_attributes(attrp, "\t");
printf("\n");
}
s = pthread_create(&thr, attrp, &thread_start, NULL);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_create");
if (attrp != NULL) {
s = pthread_attr_destroy(attrp);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_attr_destroy");
}
pause(); /* Terminates when other thread calls exit() */
}
СМОТРИТЕ ТАКЖЕ
pthread_attr_getaffinity_np(3), pthread_attr_getdetachstate(3), pthread_attr_getguardsize(3),
pthread_attr_getinheritsched(3), pthread_attr_getschedparam(3), pthread_attr_getschedpolicy(3),
pthread_attr_getscope(3), pthread_attr_getstack(3), pthread_attr_getstackaddr(3),
pthread_attr_getstacksize(3), pthread_attr_init(3), pthread_create(3), pthreads(7)
ПЕРЕВОД
Русский перевод этой страницы руководства разработал Alexey, Azamat Hackimov <azamat.hackimov@gmail.com>,
kogamatranslator49 <r.podarov@yandex.ru>, Darima Kogan <silverdk99@gmail.com>, Max Is
<ismax799@gmail.com>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>
Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной
лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или
более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.
Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом
разработчику по его адресу электронной почты или по адресу списка рассылки русских переводчиков.
Linux man-pages 6.8 2 мая 2024 г. pthread_getattr_np(3)