Linux线程浅析[线程资源回收]
- 线程的清理和控制函数
- 线程与进程对比
线程的各种状态
其实之前在看到进程的时候,子进程在死亡之后,其资源回收不了,这就导致了后台一直有个僵尸进程一直回收不了.那么在线程中呢?线程虽然是共享了其进程中的内存资源,但是其也有独立的栈等资源啊.那么线程在执行完毕之后它的资源能否进行有效回收呢??会不会有类似进程中的wait或者waitpid函数呢???答案当然是有的.
线程的清理和控制函数
在进程中我们一般使用wait或者waitpid函数,让父进程来等待子进程执行完毕之后,来释放子进程中的资源,而在线程用也有两个函数(这两个函数是一对,不可单独进行使用).这两个函数就是:pthread_cleanup_push,pthread_cleanup_pop函数:
pthread_cleanup_push ,pthread_cleanup_pop函数:
线程清理和控制函数:
#include<pthread.h>
void pthread_cleanup_push(void (*rtn)(void*),void *arg);
void pthread_cleanup_pop(int execute);
返回:成功返回0,失败返回错误编号
参数:
rtn:清理函数指针
arg:调用清理函数传递的参数
execute:值1时执行线程清理函数,值0时不执行线程清理函数
注意:在上面中其实可以看出的是push,pop那么,这里其采用的就是压栈的形式,即后进先出,后注册的,会去先执行
触发线程调用清理函数的动作 :
调用pthread_exit或者return后去执行线程清理函数
响应取消请求
用非0 execute参数调用thread_cleanup_pop时
注意:它们是一组成对出现的:等同于:
while(execute){
//执行线程处理函数
}
下面通过一个简单的小例子来看一下:同样是也类似于singal函数吧,因为在捕捉到线程死亡之后,pthread_cleanup_pop方法才会生效
/*
* ===========================================================================
*
* Filename: pthread_clean_up.c
* Description:
* Version: 1.0
* Created: 2017年03月26日 21时34分50秒
* Revision: none
* Compiler: gcc
* Author: (),
* Company:
*
* ===========================================================================
*/
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
/**
* 线程执行的清理函数(一般在这里负责相关资源的释放工作)
*/
void* clean_function(void* argv){
int *arg =(int *)argv;
printf("clean funtion pthread id:%lx\n",pthread_self());
return (void*)0;
}
/* *
* 线程的执行函数
* */
void* th_function1(void* argv){
int *arg = (int*)argv;
//
pthread_cleanup_push(clean_function,(void*)arg);
printf("pthread id:%lx,arg:%d\n",pthread_self(),arg);
pthread_cleanup_pop(arg);
return (void*)0;
}
int main(int argc,char *argv[]){
pthread_t pthread_one,pthread_two;
int result = 0;
//在线程中传入一个0,用于清理函数在注册执行的时候也去传0,pthread_cleanup_pop函数参数为0的时候是不去执行的
if((result = pthread_create(&pthread_one,NULL,th_function1,(void*)0))!=0){
perror("pthread create error");
}
//在线程中传入1,然后在通过执行函数,将1传入到清理函数中,pthread_cleanup_pop函数参数为1的时候会执行注册的函数
if((result = pthread_create(&pthread_two,NULL,th_function1,(void*)1))!=0){
perror("pthread create error");
}
pthread_join(pthread_one,NULL);
pthread_join(pthread_two,NULL);
printf("pthread:%lx is end\n",pthread_self());
return 0;
}
类比一下吧.其实这两个函数也就类似进程中singnal函数一样,但是好像其被拆分成两个函数同步去使用,一个用于注册执行的函数,一个用来注册是否去捕捉线程dead状态,所谓的清理函数,其实就是监听了线程的死亡,在线程死亡过后,需要针对这种情况做出一些响应,类似进程清理函数atexit函数
线程与进程对比
简单对比一下吧,其在不同状态下的不同函数调用
状态 | 进程 | 线程 |
---|---|---|
创建 | fork/vfork | pthead_create |
退出 | exit/return/_exit | return/pthread_exit |
等待回收 | wait/waitpid | pthread_join |
相关清理函数 | atexit | pthread_cleanup_push/pthread_cleanup_pop |
线程的各种状态
先来一副图:
看到这幅图的时候,如果除去其中的函数调用,是不是跟进程的状态图很相似.
关于这些状态就不在这里赘述.结合进程的状态图可以有更深的认识,同样也可结合java中线程的生生命周期来查看http://blog.csdn.net/qq_29924041/article/details/63255854
写的不好,还望见谅