Provided by: manpages-ru-dev_4.27.0-1_all bug

НАИМЕНОВАНИЕ

       pthread_getattr_np - возвращает атрибуты созданной нити

БИБЛИОТЕКА

       Библиотека потоков POSIX (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; отсюда и суффикс "_np" (непереносимый) в названии.

ИСТОРИЯ

       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> и Kirill Rekhov <krekhov.dev@gmail.com>

       Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной
       лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или
       более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.

       Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом
       разработчику(ам) по его(их) адресу(ам) электронной почты или по адресу списка рассылки русских
       переводчиков.

Справочные страницы Linux 6.9.1                  15 июня 2024 г.                           pthread_getattr_np(3)