Linux线程浅析[关于线程的清理,与进程的对比,以及线程的各个状态]

来源:互联网 发布:stc80c52数据手册 编辑:程序博客网 时间:2024/05/16 08:36

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

写的不好,还望见谅

欢迎持续访问博客

1 0
原创粉丝点击