线程的属性

在线程的创建接口pthread_create的参数列表中有一个类型为pthread_attr_t的参数attr,该参数用于指定新建线程的相关属性。一个线程的主要属性包括:线程栈的地址及大小,线程的调度策略与优先级,还有线程是否处于分离状态等。

属性的初始化与销毁:

#include <pthread.h>
int pthread_attr_init(pthread_attr_t *attr);  
int pthread_attr_destroy(pthread_attr_t *attr);

初始化函数(pthread_attr_init)必须在创建函数(pthread_create)之前调用。

获取指定线程的属性:

#define _GNU_SOURCE 
#include <pthread.h>
int pthread_getattr_np(pthread_t thread, pthread_attr_t *attr);

注意:要想使用该接口,必须在#include <pthread.h>前,先定义宏#define _GNU_SOURCE,因为因为pthread_getattr_np属于GNU扩展接口,而非POSIX标准。

设置和获取线程的分离状态:

#include <pthread.h>
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);

detachstate参数的取值:

PTHREAD_CREATE_JOINABLE,创建线程处于可连接状态,该值为不指定属性创建线程时的默认值。

PTHREAD_CREATE_DETACHED,新建线程处于分离状态。

设置和获取线程栈地址及大小:

#include <pthread.h>
int pthread_attr_setstack(pthread_attr_t *attr,void *stackaddr, size_t stacksize);
int pthread_attr_getstack(pthread_attr_t *attr, void **stackaddr, size_t *stacksize);
/*
filename:pthread_attr_sample.c
*/
#define _GNU_SOURCE
#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 (0 != s)
    {
        handle_error_en(s, "pthread_attr_getdetachstate");
    }

    printf("%sDetach state        = %s
",prefix, 
            (i == PTHREAD_CREATE_DETACHED) ? "PTHREAD_CREATE_DETACHED" :
            (i == PTHREAD_CREATE_JOINABLE) ? "PTHREAD_CREATE_JOINABLE" :
            "???" );

    //获取线程的栈地址及大小
     s = pthread_attr_getstack(attr, &stkaddr, &v);
     if (0 != s)
     {
         handle_error_en(s, "pthread_attr_getstack");
     }

     printf("%sStack address        = %p
", prefix, stkaddr);
     printf("%sStack size            = %0x bytes
", prefix, (unsigned)v);
}

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

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

    printf("thread attributes: 
");
    display_pthread_attr(&gattr, "	");
    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;

    /*若执行该程序带了栈大小参数,则设置新建线程为分离状态
    且根据命令行参数设置新建栈地址及大小*/
    if (argc > 1)
    {
        int stack_size;
        void *sp;
        attrp = &attr;

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

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

        //设置线程栈地址及大小
        stack_size = strtoul(argv[1], NULL, 0);
        //分配线程栈空间
        s = posix_memalign(&sp, sysconf(_SC_PAGESIZE), stack_size);
        if (0 != s)
        {
            handle_error_en(s, "posix_memalign");
        }

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

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

    s = pthread_create(&thr, attrp, &thread_start, NULL);
    if (0 != s)
    {
        handle_error_en(s, "pthread_create");
    }

    if (attrp != NULL)
    {
        s = pthread_attr_destroy(attrp);
        if (0 != s)
        {
            handle_error_en(s, "pthread_attr_destroy");
        }
    }

    pause();    //当其他线程调用exit()函数时,该线程停止。
}

运行结果:

原文地址:https://www.cnblogs.com/wanghao-boke/p/11972017.html