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