1. 线程属性
使用pthread_create函数创建新线程时,可通过类型为pthread_attr_t的attr参数指定新线程的属性,比如可以通过设置线程栈的大小来降低内存的使用,增加最大线程个数,线程调度策略和优先级等。
pthread_attr_t主要结构体成员:
typedef struct
{
int detachstate; //线程的分离状态
int schedpolicy; //线程调度策略
struct sched_param schedparam; //线程的调度参数
int inheritsched; //线程的继承性
int scope; //线程的作用域
size_t guardsize; //线程栈末尾的警戒缓冲区大小,默认是PAGE_SIZE(4096KB)
int stackaddr_set; //线程栈的设置
void* stackaddr; //线程栈的地址
size_t stacksize; //线程栈的大小
} pthread_attr_t;
可以看到pthread_attr_t可以设置很多属性,比如:设置线程分离状态,调度策略,线程栈等,但是在这里我们并不一 一介绍,只对比较常用的线程分离属性进行介绍。
2. detachstate(线程分离状态)
detachstate属性是线程的分离状态,表示线程结束时是否回收资源(比如它所使用的栈、线程结构体、线程过程函数的返回值等等)。
线程分离属性分两种情况:
PTHREAD_CREATE_JOINABLE:线程默认属性,也就是是非分离状态,表示正常启动线程,在线程结束时不回收资源,这时就需要显示的调用pthread_join函数回收。
PTHREAD_CREATE_DETACHED:线程非默认属性,分离状态,表示以分离状态启动线程,线程结束了,直接释放所占用的资源,这样就不要调用任何函数wait等待回收资源了。
3. 线程属性初始化和销毁
pthread接口允许我们通过管理线程属性函数来设置每个线程的不同属性来细调线程和同步线程的行为,例如在设置线程属性前,应该先调用线程属性初始化函数把线程属性设置为默认值,当线程退出时,销毁线程属性所占用的资源。
pthread_attr_init函数用于初始化线程属性,pthread_attr_destroy函数用于销毁线程属性。
int pthread_attr_init(pthread_attr_t *attr);
int pthread_attr_destroy(pthread_attr_t *attr);
4. 管理线程分离属性
通过上一篇我们已经了解了分离状态(参考:25-线程终止详解)。
非分离状态:是线程的默认状态,当线程运行终止后,需要调用pthread_join()函数阻塞等待回收,才能正确的释放所占用的系统资源。
管理线程分离属性的函数:
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);
参数attr:已初始化的线程属性
参数detachstate:PTHREAD_CREATE_DETACHED表示设置线程属性为分离,PTHREAD _CREATE_JOINABLE表示设置线程为非分离。
5 . 设置线程属性分离实验
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
//线程主控函数
void *tfn(void *arg) {
int n = 3;
while (n--) {
printf("thread count %d\n", n);
sleep(1);
}
return (void *)1;
}
int main(void){
pthread_t tid;
void *tret;
int err;
pthread_attr_t attr;
//初始化线程属性
pthread_attr_init(&attr);
//设置线程属性为分离状态
pthread_attr_setdetachstate(&attr , PTHREAD_CREATE_DETACHED);
pthread_create(&tid, &attr, tfn, NULL);
int state;
//获取线程属性
pthread_attr_getdetachstate(&attr , &state);
//判断线程属性是否为分离
if(state == PTHREAD_CREATE_DETACHED){
puts("pthread is PTHREAD_CREATE_DETACHED");
}
//销毁线程属性所占用的资源
pthread_attr_destroy(&attr);
//此时调用pthread_join会失败
err = pthread_join(tid, &tret);
if (err != 0){
//回收失败
fprintf(stderr, "thread %s\n", strerror(err));
}else{
fprintf(stderr, "thread exit code %d\n", (int)tret);
}
sleep(4);
return 0;
}
程序执行结果:
线程属性设置为分离状态后,调用pthread_join函数依然会失败。
6. 查看pthread线程版本
执行命令getconf GNU_LIBPTHREAD_VERSION可查看当前pthread库(线程库)版本: