PTHREAD_ATTR_INIT - Linux手册页

时间:2019-08-20 18:01:01  来源:igfitidea点击:

Linux程序员手册 第3部分
更新日期: 2020-06-09

名称

pthread_attr_init,pthread_attr_destroy-初始化和销毁​​线程属性对象

语法

#include <pthread.h>

int pthread_attr_init(pthread_attr_t *attr);
int pthread_attr_destroy(pthread_attr_t *attr);

Compile and link with -pthread.

说明

pthread_attr_init()函数使用默认属性值初始化attr指向的线程属性对象。调用之后,可以使用各种相关功能(在"另请参阅"下列出)来设置对象的各个属性,然后可以在一个或多个创建线程的pthread_create(3)调用中使用该对象。

在已初始化的线程属性对象上调用pthread_attr_init()会导致未定义的行为。

当不再需要线程属性对象时,应使用pthread_attr_destroy()函数将其销毁。销毁线程属性对象对使用该对象创建的线程无效。

线程属性对象被破坏后,可以使用pthread_attr_init()重新初始化它。对销毁的线程属性对象的任何其他使用都会产生不确定的结果。

返回值

成功时,这些函数返回0;否则,返回0。错误时,它们返回非零错误号。

错误说明

POSIX.1记录了pthread_attr_init()的ENOMEM错误;在Linux上,这些功能始终会成功(但可移植且面向未来的应用程序仍应处理可能的错误返回)。

属性

有关本节中使用的术语的说明,请参见attribute(7)。

InterfaceAttributeValue
pthread_attr_init(),pthread_attr_destroy()Thread safetyMT-Safe

遵循规范

POSIX.1-2001,POSIX.1-2008。

备注

pthread_attr_t类型应被视为不透明的:除通过pthreads函数之外,对该对象的任何访问都是不可移植的,并且会产生不确定的结果。

示例

下面的程序可选地使用pthread_attr_init()和各种相关函数来初始化用于创建单个线程的线程属性对象。创建后,线程将使用pthread_getattr_np(3)函数(非标准的GNU扩展)来检索线程的属性,然后显示这些属性。

如果程序在没有命令行参数的情况下运行,则它将NULL作为pthread_create(3)的attr参数传递,以便使用默认属性创建线程。在具有NPTL线程实现的Linux / x86-32上运行程序,我们看到以下内容:

$ ulimit -s       # No stack limit ==> default stack size is 2 MB
unlimited
$ ./a.out
Thread attributes:
        Detach state        = PTHREAD_CREATE_JOINABLE
        Scope               = PTHREAD_SCOPE_SYSTEM
        Inherit scheduler   = PTHREAD_INHERIT_SCHED
        Scheduling policy   = SCHED_OTHER
        Scheduling priority = 0
        Guard size          = 4096 bytes
        Stack address       = 0x40196000
        Stack size          = 0x201000 bytes

当我们提供堆栈大小作为命令行参数时,程序将初始化线程属性对象,在该对象中设置各种属性,并在对pthread_create(3)的调用中将指针传递给该对象。在具有NPTL线程实现的Linux / x86-32上运行程序,我们看到以下内容:

$ ./a.out 0x3000000
posix_memalign() allocated at 0x40197000
Thread attributes:
        Detach state        = PTHREAD_CREATE_DETACHED
        Scope               = PTHREAD_SCOPE_SYSTEM
        Inherit scheduler   = PTHREAD_EXPLICIT_SCHED
        Scheduling policy   = SCHED_OTHER
        Scheduling priority = 0
        Guard size          = 0 bytes
        Stack address       = 0x40197000
        Stack size          = 0x3000000 bytes

Program source

#define _GNU_SOURCE     /* To get pthread_getattr_np() declaration */
#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_pthread_attr(pthread_attr_t *attr, char *prefix)
{
    int s, i;
    size_t v;
    void *stkaddr;
    struct sched_param sp;

    s = pthread_attr_getdetachstate(attr, &i);
    if (s != 0)
        handle_error_en(s, "pthread_attr_getdetachstate");
    printf("%sDetach state        = %s\n", prefix,
            (i == PTHREAD_CREATE_DETACHED) ? "PTHREAD_CREATE_DETACHED" :
            (i == PTHREAD_CREATE_JOINABLE) ? "PTHREAD_CREATE_JOINABLE" :
            "???");

    s = pthread_attr_getscope(attr, &i);
    if (s != 0)
        handle_error_en(s, "pthread_attr_getscope");
    printf("%sScope               = %s\n", prefix,
            (i == PTHREAD_SCOPE_SYSTEM)  ? "PTHREAD_SCOPE_SYSTEM" :
            (i == PTHREAD_SCOPE_PROCESS) ? "PTHREAD_SCOPE_PROCESS" :
            "???");

    s = pthread_attr_getinheritsched(attr, &i);
    if (s != 0)
        handle_error_en(s, "pthread_attr_getinheritsched");
    printf("%sInherit scheduler   = %s\n", prefix,
            (i == PTHREAD_INHERIT_SCHED)  ? "PTHREAD_INHERIT_SCHED" :
            (i == PTHREAD_EXPLICIT_SCHED) ? "PTHREAD_EXPLICIT_SCHED" :
            "???");

    s = pthread_attr_getschedpolicy(attr, &i);
    if (s != 0)
        handle_error_en(s, "pthread_attr_getschedpolicy");
    printf("%sScheduling policy   = %s\n", prefix,
            (i == SCHED_OTHER) ? "SCHED_OTHER" :
            (i == SCHED_FIFO)  ? "SCHED_FIFO" :
            (i == SCHED_RR)    ? "SCHED_RR" :
            "???");

    s = pthread_attr_getschedparam(attr, &sp);
    if (s != 0)
        handle_error_en(s, "pthread_attr_getschedparam");
    printf("%sScheduling priority = %d\n", prefix, sp.sched_priority);

    s = pthread_attr_getguardsize(attr, &v);
    if (s != 0)
        handle_error_en(s, "pthread_attr_getguardsize");
    printf("%sGuard size          = %zu bytes\n", prefix, v);

    s = pthread_attr_getstack(attr, &stkaddr, &v);
    if (s != 0)
        handle_error_en(s, "pthread_attr_getstack");
    printf("%sStack address       = %p\n", prefix, stkaddr);
    printf("%sStack size          = 0x%zx bytes\n", prefix, v);
}

static void *
thread_start(void *arg)
{
    int s;
    pthread_attr_t gattr;

    /* pthread_getattr_np() is a non-standard GNU extension that
       retrieves the attributes of the thread specified in its
       first argument */

    s = pthread_getattr_np(pthread_self(), &gattr);
    if (s != 0)
        handle_error_en(s, "pthread_getattr_np");

    printf("Thread attributes:\n");
    display_pthread_attr(&gattr, "\t");

    exit(EXIT_SUCCESS);         /* Terminate all threads */
}

int
main(int argc, char *argv[])
{
    pthread_t thr;
    pthread_attr_t attr;
    pthread_attr_t *attrp;      /* NULL or &attr */
    int s;

    attrp = NULL;

    /* If a command-line argument was supplied, use it to set the
       stack-size attribute and set a few other thread attributes,
       and set attrp pointing to thread attributes object */

    if (argc > 1) {
        int stack_size;
        void *sp;

        attrp = &attr;

        s = pthread_attr_init(&attr);
        if (s != 0)
            handle_error_en(s, "pthread_attr_init");

        s = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
        if (s != 0)
            handle_error_en(s, "pthread_attr_setdetachstate");

        s = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
        if (s != 0)
            handle_error_en(s, "pthread_attr_setinheritsched");

        stack_size = strtoul(argv[1], NULL, 0);

        s = posix_memalign(&sp, sysconf(_SC_PAGESIZE), stack_size);
        if (s != 0)
            handle_error_en(s, "posix_memalign");

        printf("posix_memalign() allocated at %p\n", sp);

        s = pthread_attr_setstack(&attr, sp, stack_size);
        if (s != 0)
            handle_error_en(s, "pthread_attr_setstack");
    }

    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() */
}

另外参见

pthread_attr_setaffinity_np(3),pthread_attr_setdetachstate(3),pthread_attr_setguardsize(3),pthread_attr_setinheritsched(3),pthread_attr_setschedparam(3),pthread_attr_setschedpolicycy(3),pthread_attr_set(堆栈)(3),pthread_attr_setset(3),pthread_attr_setset(3) pthread_create(3),pthread_getattr_np(3),pthread_setattr_default_np(3),pthreads(7)

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/