.\" -*- coding: UTF-8 -*- '\" t .\" Copyright (c) 2008 Linux Foundation, written by Michael Kerrisk .\" .\" .\" SPDX-License-Identifier: Linux-man-pages-copyleft .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH pthread_getattr_np 3 "20 июля 2023 г." "Linux man\-pages 6.05.01" .SH ИМЯ pthread_getattr_np \- возвращает атрибуты созданной нити .SH LIBRARY POSIX threads library (\fIlibpthread\fP, \fI\-lpthread\fP) .SH СИНТАКСИС .nf \fB#define _GNU_SOURCE\fP /* Смотрите feature_test_macros(7) */ \fB#include \fP .PP \fBint pthread_getattr_np(pthread_t \fP\fIthread\fP\fB, pthread_attr_t *\fP\fIattr\fP\fB);\fP .fi .SH ОПИСАНИЕ Функция \fBpthread_getattr_np\fP() инициализирует объект атрибутов нити, на который указывает \fIattr\fP, так, чтобы он содержал актуальные значения атрибутов выполняющейся нити \fIthread\fP. .PP Возвращаемые значения атрибутов могут отличаться от соответствующих значений атрибутов переданных в объекте \fIattr\fP, который использовался при создании нити с помощью \fBpthread_create\fP(3). В частности, могут отличаться следующие атрибуты: .IP \[bu] 3 состояние отсоединения, так как присоединяемая нить могла сама отсоединиться после создания; .IP \[bu] размер стека, так как реализация нитей могла выронить значение по уместной границе. .IP \[bu] размер защиты, так как реализация нитей могла округлить значение в большую сторону до кратного размера страницы, или проигнорировать (т. е., посчитать за 0), если приложение само выделяет себе стек. .PP Кроме этого, если атрибут адреса стека не был указан в объекте атрибутов нити при создании нити, то возвращаемый объект атрибутов нити будет содержать актуальный адрес стека, который был выбран реализацией для нити. .PP Когда объект атрибутов нити, возвращаемый \fBpthread_getattr_np\fP(), больше не требуется, то он должен быть удалён с помощью \fBpthread_attr_destroy\fP(3). .SH "ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ" При успешном выполнении функция возвращает 0; при ошибке возвращается ненулевой номер ошибки. .SH ОШИБКИ .TP \fBENOMEM\fP .\" Can happen (but unlikely) while trying to allocate memory for cpuset Недостаточно памяти. .PP Также, если \fIthread\fP указывает на главную нить, то \fBpthread_getattr_np\fP() может завершиться с ошибкой из\-за ошибок различных используемых вызовов: \fBfopen\fP(3), если невозможно открыть \fI/proc/self/maps\fP; \fBgetrlimit\fP(2), если не поддерживается ограничение ресурса \fBRLIMIT_STACK\fP. .SH АТРИБУТЫ Описание терминов данного раздела смотрите в \fBattributes\fP(7). .TS allbox; lbx lb lb l l l. Интерфейс Атрибут Значение T{ .na .nh \fBpthread_getattr_np\fP() T} Безвредность в нитях MT\-Safe .TE .sp 1 .SH СТАНДАРТЫ GNU; hence the suffix "_np" (nonportable) in the name. .SH ИСТОРИЯ glibc 2.2.3. .SH ПРИМЕРЫ В программе, показанной далее, демонстрируется использование \fBpthread_getattr_np\fP(). Программа создаёт нить, которая, затем, использует \fBpthread_getattr_np\fP() для получения и показа своих атрибутов размера защиты, адреса стека и размера стека. Аргументами командной строки можно изменить эти атрибуты. Работа программы показана далее. .PP В этом запуске на системе x86\-32 нить создаётся со значениями атрибутов по умолчанию: .PP .in +4n .EX $\fB ulimit \-s\fP # Без ограничения стека ==> # размер стека по умолчанию 2 МБ unlimited $\fB ./a.out\fP Атрибуты созданной нити: Размер защиты = 4096 байт Адрес стека = 0x40196000 (EOS = 0x40397000) Размер стека = 0x201000 (2101248) байт .EE .in .PP В этом запуске мы видим, что при задании размера защиты его значение округляется до значение следующего кратного размера системной страницы (4096 байт на x86\-32): .PP .in +4n .EX $\fB ./a.out \-g 4097\fP 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 .EE .in .\".in +4n .\".nf .\"$ ./a.out \-s 0x8000 .\"Thread attributes object after initializations: .\" Guard size = 4096 bytes .\" Stack address = 0xffff8000 (EOS = (nil)) .\" Stack size = 0x8000 (32768) bytes .\" .\"Attributes of created thread: .\" Guard size = 4096 bytes .\" Stack address = 0x4001e000 (EOS = 0x40026000) .\" Stack size = 0x8000 (32768) bytes .\".fi .\".in .PP В этом запуске программа вручную выделяет стек для нити. В этом случае атрибут размера защиты игнорируется. .PP .in +4n .EX $\fB ./a.out \-g 4096 \-s 0x8000 \-a\fP 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 .EE .in .SS "Исходный код программы" .\" SRC BEGIN (pthread_getattr_np.c) \& .EX #define _GNU_SOURCE /* To get pthread_getattr_np() declaration */ #include #include #include #include #include #include \& 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\en", 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("\en"); printf("%sStack size = %#zx (%zu) bytes\en", 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:\en"); display_thread_attributes(pthread_self(), "\et"); \& 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]\en", pname); fprintf(stderr, "\et\et\-a means program should allocate stack\en"); 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 \[aq]a\[aq]: allocate_stack = 1; break; case \[aq]g\[aq]: guard_size = strtoul(optarg, NULL, 0); break; case \[aq]s\[aq]: 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\en"); \& if (argc > optind) usage(argv[0], "Extraneous command\-line arguments\en"); \& if (stack_size >= 0 || guard_size > 0) { ret_attrp = attrp; \& s = pthread_attr_init(attrp); if (s != 0) errc(EXIT_FAILURE, s, "pthread_attr_init"); } \& if (stack_size >= 0) { 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\en\en", stack_addr); \& s = pthread_attr_setstack(attrp, stack_addr, stack_size); if (s != 0) errc(EXIT_FAILURE, s, "pthread_attr_setstacksize"); } } \& if (guard_size >= 0) { 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:\en"); display_stack_related_attributes(attrp, "\et"); printf("\en"); } \& 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() */ } .EE .\" SRC END .SH "СМ. ТАКЖЕ" .ad l .nh \fBpthread_attr_getaffinity_np\fP(3), \fBpthread_attr_getdetachstate\fP(3), \fBpthread_attr_getguardsize\fP(3), \fBpthread_attr_getinheritsched\fP(3), \fBpthread_attr_getschedparam\fP(3), \fBpthread_attr_getschedpolicy\fP(3), \fBpthread_attr_getscope\fP(3), \fBpthread_attr_getstack\fP(3), \fBpthread_attr_getstackaddr\fP(3), \fBpthread_attr_getstacksize\fP(3), \fBpthread_attr_init\fP(3), \fBpthread_create\fP(3), \fBpthreads\fP(7) .PP .SH ПЕРЕВОД Русский перевод этой страницы руководства был сделан Alexey, Azamat Hackimov , kogamatranslator49 , Kogan, Max Is , Yuri Kozlov и Иван Павлов . .PP Этот перевод является бесплатной документацией; прочитайте .UR https://www.gnu.org/licenses/gpl-3.0.html Стандартную общественную лицензию GNU версии 3 .UE или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ. .PP Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на .MT man-pages-ru-talks@lists.sourceforge.net .ME .