• 【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。

  • 相关阅读:
    adb devices检测不到夜神模拟器
    adb devices检测不到夜神模拟器
    adb devices检测不到夜神模拟器
    epoll里面mmap释疑
    epoll里面mmap释疑
    epoll里面mmap释疑
    epoll里面mmap释疑
    Redis数据迁移的三个方法
    Redis数据迁移的三个方法
    MySQL:由USE DB堵塞故障引发的思考
  • 原文地址:https://www.cnblogs.com/huty/p/8518633.html
Copyright © 2020-2023  润新知