Linux C 线程

本文探讨了pthread_detach在多线程程序中的作用及其对内存管理的影响。解释了如果不正确使用此函数可能导致内存泄漏的问题,并提供了如何避免此类问题的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.  没有pthread_detach导致内存泄漏 

#include <pthread.h>

#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>

void  doprint(void *arg){
    printf("arg=%d\n",*(int *)arg);
    pthread_detach(pthread_self());
}

void main (){
    pthread_t pid ;
    int count = 0;
    while(count < 10000){
        pthread_create(&pid,NULL,doprint,&count);
        usleep(10000);
        count++;
    }
    printf("end count=%d\n",count);

}

  PID       Vss      Rss      Pss      Uss     Swap    PSwap    USwap    ZSwap  cmdline
  448  1253112K  145028K   52131K   34856K    3820K    1695K    1560K     501K  system_server
  932  1230132K  132032K   42376K   31248K    2412K     232K      96K      68K  com.android.systemui
 1098  1177852K  113520K   24575K   10668K    6896K    3345K    2972K     988K  com.android.settings
 1525  1155976K  109036K   23866K   14320K    2304K     136K       0K      40K  com.android.launcher3
  876   1171652K   97424K   19977K   12112K    2484K     230K      88K      68K  com.android.phone
19161 3123964K   14772K   12736K   12704K       0K       0K       0K       0K  ./data/test
  896   1157256K   83764K   12699K    6928K    2656K     392K     248K     115K  com.android.bluetooth

 1550  1122764K   76592K   11347K    6040K    4804K    1106K     708K     327K  android.process.media

可以看到test进程,Vss几乎吧3G的用户空间虚拟地址都用完了。

 

加了pthread_detach之后

20761     4980K    2324K     399K     376K          0K           0K          0K       0K  ./data/test

 

或者在创建线程时,添加属性,用法如下:

 5 // 或者创建线程前设置 PTHREAD_CREATE_DETACHED 属性
 6 pthread_attr_t attr;
 7 pthread_t thread;
 8 pthread_attr_init (&attr);
 9 pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
10 pthread_create (&thread, &attr&thread_function, NULL);

11 pthread_attr_destroy (&attr);

 

 

 

下面这段转自http://www.hack6.com/html/bc/C/20141106/52232.html

在任何一个时间点上,线程是可结合的(joinable)或者是分离的(detached)。一个可结合的线程能够被其他线程收回其资源和杀死。在被其他线程回收之前,它的存储器资源(例如栈)是不释放的。相反,一个分离的线程是不能被其他线程回收或杀死的,它的存储器资源在它终止时由系统自动释放。

    默认情况下,线程被创建成可结合的。为了避免存储器泄漏,每个可结合线程都应该要么被显示地回收,即调用pthread_join;要么通过调用pthread_detach函数被分离。

[cpp]

int pthread_join(pthread_t tid, void**thread_return); 

                                 若成功则返回0,若出错则为非零。 

int pthread_join(pthread_t tid, void**thread_return);

                                 若成功则返回0,若出错则为非零。    线程通过调用pthread_join函数等待其他线程终止。pthread_join函数分阻塞,直到线程tid终止,将线程例程返回的(void*)指针赋值为thread_return指向的位置,然后回收已终止线程占用的所有存储器资源。[cpp] view plaincopyprint?int pthread_detach(pthread_t tid); 

                                 若成功则返回0,若出错则为非零。 

int pthread_detach(pthread_t tid);

                                 若成功则返回0,若出错则为非零。

    pthread_detach用于分离可结合线程tid。线程能够通过以pthread_self()为参数的pthread_detach调用来分离它们自己。

    如果一个可结合线程结束运行但没有被join,则它的状态类似于进程中的Zombie Process,即还有一部分资源没有被回收,所以创建线程者应该调用pthread_join来等待线程运行结束,并可得到线程的退出代码,回收其资源。

    由于调用pthread_join后,如果该线程没有运行结束,调用者会被阻塞,在有些情况下我们并不希望如此。例如,在Web服务器中当主线程为每个新来的连接请求创建一个子线程进行处理的时候,主线程并不希望因为调用pthread_join而阻塞(因为还要继续处理之后到来的连接请求),这时可以在子线程中加入代码

    pthread_detach(pthread_self())

或者父线程调用

    pthread_detach(thread_id)(非阻塞,可立即返回)

这将该子线程的状态设置为分离的(detached),如此一来,该线程运行结束后会自动释放所有资源

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值