PTHREAD_GETATTR_NP(3)

NOM
pthread_getattr_np - Obtenir les attributs d'un thread créé

SYNOPSIS
#define _GNU_SOURCE             /* Consultez feature_test_macros(7) */
#include <pthread.h>

int pthread_getattr_np(pthread_t thread, pthread_attr_t *attr);

Compiler et éditer les liens avec -pthreads.

DESCRIPTION
La fonction pthread_getattr_np() initialise l'objet d'attributs de thread auquel attr fait référence de telle sorte qu'il contienne les valeurs d'attributs qui décrivent le thread thread en cours d'exécution.

Les valeurs d'attribut renvoyées peuvent être différentes des valeurs d'attribut correspondantes fournies dans l'objet attr utilisé pour créer le thread avec pthread_create(3). En particulier, les attributs suivants peuvent changer :

–   l'état détaché ou non, puisqu'un thread fusionné peut s'être détaché lui même après sa création ;

–   la taille de la pile, que l'implémentation peut aligner sur une limite plus appropriée.

–   et la taille de garde, que l'implémentation peut arrondir au multiple supérieur de la taille de page ou ignorer (c'est-à-dire, considérer qu'elle vaut 0) si l'application alloue sa propre pile.

De plus, si l'attribut contenant l'adresse de la pile n'était pas défini dans l'objet d'attributs de thread utilisé pour créer le thread, alors l'objet d'attributs de thread renvoyé contiendra l'adresse effective de la pile que l'implémentation a choisit pour le thread.

Quand l'objet d'attributs de thread renvoyé par pthread_getattr_np() n'est plus nécessaire, il devrait être détruit à l'aide de pthread_attr_destroy(3).

VALEUR RENVOYÉE
En cas de réussite, cette fonction renvoie 0 ; en cas d'erreur, elle renvoie un numéro d'erreur non nul.

ERREURS

ENOMEM
    Mémoire insuffisante.

De plus, si thread se réfère à à un thread principal, alors pthread_getattr_np() peut échouer à cause de différents appels sous-jacents : fopen(3), si /proc/self/maps ne peut être ouvert, et getrlimit(2), si la limite de ressources RLIMIT_STACK n'est pas prise en charge.

VERSIONS
Cette fonction est disponible dans la glibc depuis la version 2.2.3.

ATTRIBUTS
Pour une explication des termes utilisés dans cette section, consulter attributes(7).
Interface | Attribut | Valeur
pthread_getattr_np() | Sécurité des threads | MT-Safe

CONFORMITÉ
Cette fonction est une extension GNU non standard ; c'est la raison du suffixe « _np » (non portable) dans son nom.

EXEMPLES
Le programme ci-dessous démontre l'utilisation de pthread_getattr_np(). Le programme crée un thread qui utilise ensuite pthread_getattr_np() pour récupérer et afficher les attributs contenant la taille de la garde, l'adresse de la pile et la taille de la pile. Des paramètres en ligne de commande peuvent être utilisés pour définir les attributs qui seront utilisés pour créer le thread à des valeurs autres que les valeurs par défaut. Les sessions d'interpréteur de commande ci-dessous démontrent l'utilisation du programme.

Lors de la première exécution, sur une système x86-32, un thread est créé en utilisant les attributs par défaut :

    $ ulimit -s      # No stack limit ==> default stack size is 2 MB
    unlimited
    $ ./a.out
    Attributes of created thread:
            Guard size          = 4096 bytes
            Stack address       = 0x40196000 (EOS = 0x40397000)
            Stack size          = 0x201000 (2101248) bytes

Lors de l'exécution suivante, nous voyons que si la taille de la garde est fournie, elle est arrondie (vers le haut) au prochain multiple de la taille de page système (4096 octets sous 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

Lors de la dernière exécution, le programme alloue manuellement une pile pour le thread. Dans ce cas, l'attribut contenant la taille de la garde est ignorée.

    $ ./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

  Source du programme
    #define _GNU_SOURCE     /* Pour la déclaration de pthread_getattr_np() */
    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #define handle_error_en(en, msg) \
            do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
    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)
            handle_error_en(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)
            handle_error_en(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)
            handle_error_en(s, "pthread_getattr_np");
        display_stack_related_attributes(&attr, prefix);
        s = pthread_attr_destroy(&attr);
        if (s != 0)
            handle_error_en(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 >= 0 || guard_size > 0) {
            ret_attrp = attrp;
            s = pthread_attr_init(attrp);
            if (s != 0)
                handle_error_en(s, "pthread_attr_init");
        }
        if (stack_size >= 0) {
            if (!allocate_stack) {
                s = pthread_attr_setstacksize(attrp, stack_size);
                if (s != 0)
                    handle_error_en(s, "pthread_attr_setstacksize");
            } else {
                s = posix_memalign(&stack_addr, sysconf(_SC_PAGESIZE),
                                   stack_size);
                if (s != 0)
                    handle_error_en(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)
                    handle_error_en(s, "pthread_attr_setstacksize");
            }
        }
        if (guard_size >= 0) {
            s = pthread_attr_setguardsize(attrp, guard_size);
            if (s != 0)
                handle_error_en(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)
            handle_error_en(s, "pthread_create");
        if (attrp != NULL) {
            s = pthread_attr_destroy(attrp);
            if (s != 0)
                handle_error_en(s, "pthread_attr_destroy");
        }
        pause();    /* Terminates when other thread calls exit() */
    }

VOIR AUSSI
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)

COLOPHON
Cette page fait partie de la publication 5.13 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies et la dernière version de cette page peuvent être trouvées à l'adresse https://www.kernel.org/doc/man-pages/.

TRADUCTION
La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org> et Frédéric Hantrais <fhantrais@gmail.com>

Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 (https://www.gnu.org/licenses/gpl-3.0.html) concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org.