1. 线程属性:
线程属性主要包含分离状态,作用域,栈尺寸,栈地址,优先级,调度策略和参数,本节主要介绍栈尺寸和分离状态
线程属性通过pthread_attr_t进行表达,定义如下:
union pthread_attr_t { char _size_[__SIZEOF_PTHREAD_ATTR_T]; long int __align; }
2. 获取线程属性函数
- 初始化线程属性结构体
int pthread_attr_init(pthread_attr_t *attr)
attr:需要初始化的属性结构体
成功:0, 失败:errno - 销毁线程属性结构体
int pthread_attr_destory(pthread_attr_t *attr)
attr:需要销毁的属性结构体
成功:0,失败:errno
上面这两个API函数主要用与刚创建线程的时候 - 获取线程属性结构体
int pthread_getattr_np(pthread_t thread, pthread_attr_t *attr)
thread:要获取的线程标示,attr:返回线程属性参数
成功:0,失败:errno
3. 线程属性---分离状态(POSIX)
分离状态决定着一个线程及以何种方式终止自己,默认的属性则是非分离状态的
分离状态和非分离状态的区别:
- 非分离状态:该线程结束后的资源是不会自动回收的,无论结束方式是线程主动结束还是被其他线程取消,必须调用pthread_join(),否则该线程将成为一个僵尸线程,因为线程已经结束,但是资源却没有被回收
- 分离状态:这种线程结束时会自动回收资源
- 创建分离状态线程
1)int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
attr:线程属性结构体,detachstate:分离状态参数 PTHREAD_CREATE_DETACHED,PTHREAD_CREATE_JOINABLE
成功:0, 错误:errno
2) int pthread_detach(pthread_t thread)
thread:要分离的线程标示
成功:0,错误:errno - 从个人角度分析主线程和进程,其实在很长时间上我认为二者没有任何区别,现在发现,主线程是可以先于进程结束的,也就时说子线程可以晚于主线程退出,代码如下
#include <stdio.h> #include <pthread.h> #include <unistd.h> #include <string.h> void *pth_fun(void *arg) { printf("Hi, I am a pthread!\n"); return 0; } int main(void) { pthread_t pth; pthread_attr_t attr; int rs = 0; // 初始化一个线程属性参数 rs = pthread_attr_init(&attr); if (rs) { printf("init attr error!, rs = %d\n", rs); return -1; } // 设置可分离参数 rs = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); if(rs) { printf("set detach error, rs = %d\n", rs); return -1; } // 创建线程 rs = pthread_create(&pth, &attr, pth_fun, NULL); if(rs) { printf("pthread create error, reason = %d\n", rs); return -1; } // 销毁参数 rs = pthread_attr_destroy(&attr); if(rs) { printf("destroy attr error, rs = %d\n", rs); } printf("main pthread will be end!\n"); // 主线程先退出 pthread_exit(NULL); printf("I will never be there!\n"); return 0; }
执行结果如下:
kunmzhao@build-245:~/study$ gcc temp.c -o temp -lpthread
kunmzhao@build-245:~/study$ ./temp
main pthread will be end!
Hi, I am a pthread!
kunmzhao@build-245:~/study$
4. 线程属性---栈空间
- 占空间:指的是开辟线程消耗的占空间,默认值是8M左右,最小值是16KB,栈空间主要储存的是局部变量,函数参数,返回地址等,在实际中我们视情况而定,不需要计算的很精确
- 设置栈空间
int pthread_attr_setstacksize(pthread_attr_t * attr, size_t size)
attr:线程属性参数, size:设置栈空间的大小
成功:0, 失败:errno - 获得线程栈空间
int pthread_attr_getstacksize(pthread_attr_t *attr, size_t * stacksize)
attr:线程属性参数,stacksize:栈空间大小
成功:0,失败:errno - 代码如下:
#define _GNU_SOURCE #include <stdio.h> #include <pthread.h> #include <unistd.h> #include <string.h> // 默认线程栈空间大小 void *pth_fun(void *arg) { printf("Hi, I am a pthread!\n"); pthread_attr_t attr; int rs = pthread_getattr_np(pthread_self(), &attr); size_t size = 0; rs = pthread_attr_getstacksize(&attr, &size); printf("pthread size = %ld bytes\n", size); return 0; } // 设置栈空间最小值 void *pth_fun2(void *arg) { printf("Hi, I am a pthread2!\n"); pthread_attr_t attr; int rs = pthread_getattr_np(pthread_self(), &attr); size_t size = 0; rs = pthread_attr_getstacksize(&attr, &size); printf("default pthread size = %ld bytes\n", size); return 0; } int main(void) { pthread_t pth,pth2; pthread_attr_t attr; int rs = 0; int size = 0; rs = pthread_create(&pth2, NULL, pth_fun2, NULL); rs = pthread_attr_init(&attr); if (rs) { printf("init attr error!, rs = %d\n", rs); return -1; } rs = pthread_attr_setstacksize(&attr, 16384); rs = pthread_create(&pth, &attr, pth_fun, NULL); if(rs) { printf("pthread create error, reason = %d\n", rs); return -1; } sleep(2); printf("main pthread will be end!\n"); return 0; }
运行结果如下:
kunmzhao@build-245:~/study$ gcc temp.c -o temp -lpthread
kunmzhao@build-245:~/study$ ./temp
Hi, I am a pthread2!
Hi, I am a pthread!
default pthread size = 8392704 bytes
pthread size = 16384 bytes
main pthread will be end!
kunmzhao@build-245:~/study$