• 【Linux开发】彻底释放Linux线程的资源


    Linux系统中程序的线程资源是有限的,表现为对于一个程序其能同时运行的线程数是有限的。而默认的条件下,一个线程结束后,其对应的资源不会被释放,于是,如果在一个程序中,反复建立线程,而线程又默认的退出,则最终线程资源耗尽,进程将不再能建立新的线程。

    解决这个问题,有2种方式,系统自动释放线程资源,或者由另一个线程释放该线程资源。

    注意,在这里,我认为进程运行后,本身,也是一个线程,主线程,主线程和主线程建立的线程共享进程资源。不同于其他线程,在于主线程运行结束后,程序退出,所有程序建立的线程也会退出。

    系统自动释放
           如果想在线程结束时,由系统释放线程资源,则需要设置线程属性为detach。

    代码上,可以这样表示:

    pthread_t t;
    pthread_attr_t a; //线程属性
    pthread_attr_init(&a);  //初始化线程属性
    pthread_attr_setdetachstate(&a, PTHREAD_CREATE_DETACHED);      //设置线程属性
    ::pthread_create( &t, &a, GetAndSaveAuthviewSDRStub, (void*)lp);                   //建立线程

    其他线程释放
           另一种方式,则是由另一个线程将该资源释放。

    代码上,可以这样表示:

    pthread_t t;
    ::pthread_create( NULL, NULL, GetAndSaveAuthviewSDRStub, (void*)lp);
    ::pthread_join( t);

             ::pthread_join( t)等待线程t退出,并释放t线程所占用的资源。当然,这里也有个同步的功能,使一个线程等待另一个线程退出,然后才继续运行。

     

     

     linux线程执行和windows不同,pthread有两种状态joinable状态和unjoinable状态,如果线程是joinable状态,当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符(总计8K多)。只有当你调用了pthread_join之后这些资源才会被释放。
    若是unjoinable状态的线程,这些资源在线程函数退出时或pthread_exit时自动会被释放。

    unjoinable属性可以在pthread_create时指定,或在线程创建后在线程中pthread_detach自己,如:pthread_detach(pthread_self()),将状态改为unjoinable状态,确保资源的释放。或者将线程置为joinable,然后适时调用pthread_join.

    在程序运行中检查/proc/ <pid> /maps文件,若看到大概8K左右的很多虚拟内存碎片,基本上可以确认是线程资源泄漏造成的300个线程后pthread_create失败。

    不知是否因为自己,先对要创建的线程做了以下属性设定,
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    然后又在线程函数中使用
    pthread_detach(pthread_self());

    两段代码作用有冲突。

    ===============================================================================

    pthread_detach(threadid)和pthread_detach(pthread_self())的区别应该是调用他们的线程不同,没其他区别。

    pthread_detach(threadid)函数的功能是使线程ID为threadid的线程处于分离状态,一旦线程处于分离状态,该线程终止时底层资源立即被回收;否则终止子线程的状态会一直保存(占用系统资源)直到主线程调用pthread_join(threadid,NULL)获取线程的退出状态。
    通常是主线程使用pthread_create()创建子线程以后,一般可以调用pthread_detach(threadid)分离刚刚创建的子线程,这里的threadid是指子线程的threadid;如此以来,该子线程止时底层资源立即被回收;
    被创建的子线程也可以自己分离自己,子线程调用pthread_detach(pthread_self())就是分离自己,因为pthread_self()这个函数返回的就是自己本身的线程ID。

  • 相关阅读:
    多个类定义attr属性重复的问题:Attribute "xxx" has already been defined
    好用的批量改名工具——文件批量改名工具V2.0 绿色版
    得到ImageView中drawable显示的区域的计算方法
    得到view坐标的各种方法
    实现类似于QQ空间相册的点击图片放大,再点后缩小回原来位置
    Material Designer的低版本兼容实现(五)—— ActivityOptionsCompat
    Android 自带图标库 android.R.drawable
    解决 Attempting to destroy the window while drawing!
    解决Using 1.7 requires compiling with Android 4.4 (KitKat); currently using API 4
    Material Designer的低版本兼容实现(四)—— ToolBar
  • 原文地址:https://www.cnblogs.com/huty/p/8518632.html
Copyright © 2020-2023  润新知