首先说明线程中要回收哪些资源,理解清楚了这点之后在思考资源回收的问题。
1、子线程创建时从父线程copy出来的栈内存;
线程退出有多种方式,如return,pthread_exit,pthread_cancel等;线程分为可结合的(joinable)和 分离的(detached)两种,如果没有在创建线程时设置线程的属性为PTHREAD_CREATE_DETACHED,则线程默认是可结合的。可结合的线程在线程退出后不会立即释放资源,必须要调用pthread_join来显式的结束线程。分离的线程在线程退出时系统会自动回收资源。
对于这类资源,主要通过 【设置分离属性 】和 【 pthread_join()】 两种方法来处理。
其中设置分离属性又可以分别用【pthread_attr_setdetachstat()】和【pthread_detach()】来处理。
2、子线程内部单独申请的堆内存(malloc、realloc、calloc)和锁资源mutex;
一旦又处于挂起状态的取消请求(即加锁之后,解锁之前),线程在执行到取消点时如果只是草草收场,这会将共享变量以及pthreads对象(例如互斥量)置于一种不一致状态,可能导致进程中其他线程产生错误结果、死锁,甚至造成程序崩溃。为避免这一问题:
使用清理函数pthread_cleanup_push()和pthread_cleanup_pop()来处理。
线程退出和资源回收
线程退出有多种方式,如return,pthread_exit,pthread_cancel等;线程分为可结合的(joinable)和 分离的(detached)两种,如果没有在创建线程时设置线程的属性为PTHREAD_CREATE_DETACHED,则线程默认是可结合的。可结合的线程在线程退出后不会立即释放资源,必须要调用pthread_join来显式的结束线程。分离的线程在线程退出时系统会自动回收资源。
一、设置分离线程的几种方法:
1.在创建线程时加上
pthread_attr_t attr;
pthread_t thread;
pthread_attr_init (&attr);
/* 设置线程的属性为分离的 */
pthread_attr_setdetachstat(&attr, PTHREAD_CREATE_DETACHED);
pthread_create (&thread, &attr, &thread_function, NULL);
/* 销毁一个目标结构,并且使它在重新初始化之前不能重新使用 */
pthread_attr_destroy (&attr);
2.在线程中调用pthread_detach(pthread_self());
3.主线程中调用pthread_detach(pid),pid为子线程的线程号
要注意的是,设置为分离的线程是不能调用pthread_join的,调用后会出错
二、可结合的线程的几种退出方式
1. 子线程使用return退出,主线程中使用pthread_join回收线程
2.子线程使用pthread_exit退出,主线程中使用pthread_join接收pthread_exit的返回值,并回收线程
3.主线程中调用pthread_cancel,然后调用pthread_join回收线程
注意:在要杀死额子线程对应的处理函数的内部
pthread_cancel函数执行的条件:
1、产生了系统调用(sleep、read、write、open等系统接口)
2、pthread_testcancel();//设置取消点
线程属性结构如下:
typedef struct
{
int detachstate; //线程的分离状态
int schedpolicy; // 线程调度策略
structsched_param schedparam; //线程的调度参数
int inheritsched; //线程的继承性
int scope; //线程的作用域
size_t guardsize; //线程栈末尾的警戒缓冲区大小
int stackaddr_set;
void* stackaddr; //线程栈的位置
size_t stacksize; //线程栈的大小
}pthread_attr_t;
转载自原文链接, 如需删除请联系管理员。
原文链接:Linux线程退出、资源回收、资源清理的方法,转载请注明来源!