pthread_attr_t 控制线程属性结构体

typedef struct __pthread_attr_s
{

    int __detachstate; 

    int __schedpolicy;

    struct __sched_param __schedparam;

    int __inheritsched;

    int __scope;

    size_t __guardsize;

    int __stackaddr_set;

    void *__stackaddr;

    size_t __stacksize;表示堆栈的大小。

}pthread_attr_t;


int __detachstate;
        设置线程是否和其他线程同步(其他线程能否调用pthread_join()),也可以在新线程运行中调用pthread_detach() 完成。有两个值,PTHREAD_CREATE_DETACHEDPTHREAD_CREATE_JOINABLE,默认值是后者,后者情况下线程的资源在退出后自行释放。设置为PTHREAD_CREATE_DETACH状态(不论是创建时设置还是运行时设置) 则不能再恢复到PTHREAD_CREATE_JOINABLE状态。
int __schedpolicy;                   
        线程的调度策略, 可以用pthread_setschedparam设置,有效值为SCHED_OTHER(正常、非实时)、SCHED_RR(实时、轮转法)和SCHED_FIFO(实时、先入先出)。缺省为SCHED_OTHER,后两种调度策略仅对超级用户有效。运行时可以用过pthread_setschedparam()来改变。

struct __sched_param __schedparam;   
        调度参数,目前仅有一个sched_priority整型变量表示线程的运行优先级,表示线程的优先级,只在调度策略为SCHED_RRSCHED_FIFO 有效, 并可以在运行时通过pthread_setschedparam()函数来改变,缺省为0
int __inheritsched;
        有两种值可供选择:PTHREAD_EXPLICIT_SCHEDPTHREAD_INHERIT_SCHED,前者表示新线程使用显式指定调度策略和调度参数(即attr中的值),而后者表示继承调用者线程的值。缺省为PTHREAD_EXPLICIT_SCHED。
int __scope;
        表示线程间竞争CPU的范围,也就是说线程\优先级的有效范围。POSIX的标准中定义了两值:PTHREAD_SCOPE_SYSTEMPTHREAD_SCOPE_PROCESS,前者表示与系统中所有线程一起竞争CPU时间,后者表示仅与同进程中的线程竞争CPU。目前LinuxThreads仅实现了PTHREAD_SCOPE_SYSTEM一值。


设置pthread_attr_t相关函数:
1.初始化

    pthread_attr_init(&attr)
    初始化的值为:

    __scope = PTHREAD_SCOPE_PROCESS
    __tetachstate = PTHREAD_CREATE_JOINABL
    __stackaddr = NULL
    __stacksize = 1M
    __sched_param.priority = 0 (使用创建线程的优先级)
    __inheritsched = PTHREAD_INHERIT_SCHED
    __schedpolicy = SCHED_OTHER

2.反初始化:

    pthread_attr_destroy(&attr)

3.设置关联标志:

    int pthread_attr_setdetachstate(pthread_attr_t*tattr, int detachstate);

    detachstate =PTHREAD_CREATE_JOINABLE/PTHREAD_CREATE_DETACHED设置PTHREAD_CREATE_DETACHED表示线程在退出后资源自动释放,不需要调用pthread_join

4.查询关联标志:

    int pthread_attr_getdetachstate(const pthread_attr_t*tattr, int *detachstate)

5.设置cpu竞争模式:

    int pthread_attr_setscope(pthread_attr_t *tattr,intscope);
    scope = PTHREAD_SCOPE_SYSTEM/PTHREAD_SCOPE_PROCESS

6.查询cpu竞争模式:
   int pthread_attr_getscope(pthread_attr_t *tattr, intscope);

7.设置调度策略
   int pthread_attr_setschedpolicy(pthread_attr_t*tattr, int policy);
   policy = SCHED_OTHER/SCHED_RR/SCHED_FIFO

8.查询调度策略:
   int pthread_attr_getschedpolicy(pthread_attr_t*tattr, int policy);

9.设置继承模式:
   int pthread_attr_setinheritsched(pthread_attr_t*tattr, int inherit);
   inherit =PTHREAD_INHERIT_SCHED/PTHREAD_EXPLICIT_SCHED

10.查询继承模式:
   int pthread_attr_getinheritsched(pthread_attr_t*tattr, int inherit);

11.设置优先级:
   int pthread_attr_setschedparam(pthread_attr_t *tattr,const struct sched_param *param);

12.查询优先级:
   int pthread_attr_getschedparam(pthread_attr_t *tattr,const struct sched_param *param);

13.设置堆栈大小:
   int pthread_attr_setstacksize(pthread_attr_t *tattr,int size);

   默认情况下线程保留1M的,而且会在堆栈的顶增加一个空闲的内存页,当访问该内存页的时候就会触发SIGSEGV信号,如果开发者设置了stack size那么就需要用户制定这个多余的内存页并且通过mprotect函数设置保护标志,而且它必须设置PTHREAD_CREATE_JOINABLE关联模式,因为只有其他线程调用pthread_join后分配的资源才会被释放, 线程的堆栈的分配必须大于一个最小值PTHREAD_STACK_MIN() 。当分配内的时候会设置MAP_NORESERVE标志(mmap),这个标志表示不预留交换空间,当对该内存进行写的时候,如果系统不能分配到交换空间,那么就会触发SIGSEGV信号,如果可以分配到交换空间,那么就会把private page复制到交换空间。如果mmap没有指定MAP_NORESERVE,在分配空间的时候就会保留和映射区域相同大小的交换空间(这个其实就是资源的滞后分配原则)

14.查询堆栈大小:
    int pthread_attr_getstacksize(pthread_attr_t *tattr,int size);

15.设置堆栈地址:
    int pthread_attr_setstackaddr(pthread_attr_t*tattr,void **stackaddr);

    如果线程地址为NULL,那么pthread分配指定的内存(1M)或者是指定的堆栈大小,如果设定了堆栈的地址那么内存的分配必须由开发者设定,例如:
    stackbase = (void *) malloc(size);
    ret = pthread_attr_setstacksize(&tattr, size);
    ret = pthread_attr_setstackaddr(&tattr, stackbase);
    ret = pthread_create(&tid, &tattr, func, arg);

16.查询堆栈地址:
    int pthread_attr_getstackaddr(pthread_attr_t*tattr,void **stackaddr);

17.等待线程终止:

    int pthread_join(thread_t tid, void **status);

    等待线程结束,这个函数会阻塞调用线程,如果多个线程同时等待一个线程,只有一个线程会成功返回,其他线程将会返回错误值ESRCH(无效的线程, 等待的线程).其他错误值包括:EDEADLK:自己等待自己; EINVAL: tid无效。int pthread_detach(thread_t tid);将线程和其他线程脱离同步,别的线程不能对它调用pthread_join(),而且它的资源也是在退出时自行释放。

18.创建TSD key:
    int pthread_key_create(pthread_key_t *key, void(*destructor) (void *));

    通常在创建线程前创建,然后在新创建线程中使用,void(*destructor)(void *)这是线程退出时如果TSD 变量不是NULL , 就会调用destructor 。pthread_key_create通常与pthread_once结合使用,以保证创建TSD只执行一次,如下:
    static pthread_once_t key_only_one =PTHREAD_ONCE_INIT;
    pthread_once(&key_only_one, key_create_function);
    void key_create_function(void)
    {
          pthread_key_create(&key_obj, free_key);
    }
    void free_key(void *arg)
    {
         free(arg);
    }

19.删除TSD key:
    int pthread_key_delete(pthread_key_t *key);

20.设定TSD key对应的值:
    int pthread_setspecific(pthread_key_t key, const void*value);



猜你喜欢

转载自blog.csdn.net/woxiangzi/article/details/50894588
今日推荐