PTHREAD_ATTR_INIT

Posted on 2012-03-19 16:18  无忧consume  阅读(994)  评论(0编辑  收藏  举报

http://cpp.ezbty.org/import_doc/linux_manpage/pthread_attr_destroy.3.html

名字

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);

编译并与 -pthread 一起链接。

描述

pthread_attr_init() 使用默认属性值来初始化 attr
指向的线程属性对象。在这个调用之后,单独的对象属性可以通过一组相关的函数来设定(在下面“参见”小结列出),其后这个对象可以被一次或多次用于创建线程的
pthread_create(3) 调用。

在一个已经初始化的线程属性对象上调用 pthread_attr_init() 其结果是未定义的。
当一个线程属性对象不再使用时,它应该使用 pthread_attr_destroy() 函数来销毁。销毁一个线程属性对象对使用这个对象创建的线程没有影响。
在一个线程属性对象被销毁之后,它能再次调用 pthread_attr_init() 来初始化。险些之外,对已经销毁的线程属性对象任何其它使用其结果都未定义的。

返回值

成功时,这些函数返回0;如果错误,它们返回非0值。

错误

POSIX.1-2001 为 pthread_attr_init() 说明了一个 ENOMEM 错误:Linux
上的这些函数总是会成功(但一个可移植的程序应该处理这个永远也不会返回的错误)。

遵循于

POSIX.1-2001.

注意

pthread_attr_t 类型应该对用户透明:任何不是通过 pthreads 函数对其对象的操作都是不可移植的,并且产生未定义的结果。

示例

下面这个程序使用 pthread_attr_init()
和一组相关的函数来初始一个线程属性对象,接着使用这个对象创建一个线程。一旦创建成功,该线程使用 pthread_getattr_np(3)
函数(非标准的 GNU 扩展)来获得自身的线程属性,接着显示这个属性。

如果这个程序运行时没有提供命令行参数,那么它将使用参数 attr 为空指针的 pthread_create(3),因此线程使用默认的属性来创建。在 Linux/x86-32 系统里使用 NPTL 线程实现,运行这个程序我将看到:
$ ulimit -s     # 没有栈限制 ==> 默认栈尺寸是 2MB
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) 调用。在 Linux/x86-32 系统里使用 NPTL 线程实现,运行这个程序我将看到:
$ ./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

程序源码


#define _GNU_SOURCE /* 引入 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_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 = %d 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%x bytes\n", prefix, v);
}

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

    /* pthread_getattr_np() 一个非标准的 GNU 扩展,
        它用于取得其第一个参数引用的线程的属性。*/

    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); /* 终止所有线程 */
}

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

    attrp = NULL;

    /* 如果命令行参数提供了,使用它来设置线尺寸属性,
        以及一些其它属性,并设置 attrp 指向这个线程属性对象 */

    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(); /* 当其它线程调用 exit() 时终止 */
}

参看

pthread_attr_setaffinity_np(3), pthread_attr_setdetachstate(3),
pthread_attr_setguardsize(3), pthread_attr_setinheritsched(3),
pthread_attr_setschedparam(3), pthread_attr_setschedpolicy(3),
pthread_attr_setscope(3), pthread_attr_setstack(3),
pthread_attr_setstackaddr(3), pthread_attr_setstacksize(3),
pthread_create(3), pthread_getattr_np(3), pthreads(7)

Copyright © 2024 无忧consume
Powered by .NET 8.0 on Kubernetes