• 线程的属性


    在线程的创建接口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()函数时,该线程停止。
    }

    运行结果:

  • 相关阅读:
    《程序员成长的烦恼》
    我们一起读《暗时间》
    CSS选择器分类总结
    CSharp如何自定义鼠标样式
    Android开发消除横向排列的多个Button之间的空隙
    JS代码指导原则
    Android蓝牙联机Demo解析
    排序算法之堆排序(Heapsort)解析
    排序算法之归并排序(Mergesort)解析
    经典串匹配算法(KMP)解析
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/11972017.html
Copyright © 2020-2023  润新知