這兩天在看Pthread 資料的時候,無意中看到這樣一句話(man pthread_detach):
Either pthread_join(3) or pthread_detach() should be called for each thread
that an application creates, so that system resources for the thread can be
released. (But note that the resources of all threads are freed when the
process terminates.)
也就是說:每個進程創(chuàng)建以后都應(yīng)該調(diào)用pthread_join 或 pthread_detach 函數(shù),只有這樣在線程結(jié)束的時候資源(線程的描述信息和stack)才能被釋放.
之后又查了pthread_join 但是沒有明確說明必須調(diào)用pthread_join 或 pthread_detach.
但是再查了 Pthread for win32 pthread_join
When a joinable thread terminates, its memory resources (thread descriptor and stack) are not deallocated until another thread performs pthread_join on it. Therefore, pthread_join must be called once for each joinable thread created to avoid memory leaks.
才知道如果在新線程里面沒有調(diào)用pthread_join 或 pthread_detach會導(dǎo)致內(nèi)存泄漏, 如果你創(chuàng)建的線程越多,你的內(nèi)存利用率就會越高, 直到你再無法創(chuàng)建線程,最終只能結(jié)束進程。
解決方法有三個:
1. 線程里面調(diào)用 pthread_detach(pthread_self()) 這個方法最簡單
2. 在創(chuàng)建線程的設(shè)置PTHREAD_CREATE_DETACHED屬性
3. 創(chuàng)建線程后用 pthread_join() 一直等待子線程結(jié)束。
下面是幾個簡單的例子
1. 調(diào)用 pthread_detach(pthread_self())
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *PrintHello(void)
{
pthread_detach(pthread_self());
int stack[1024 * 20] = {0,};
//sleep(1);
long tid = 0;
//printf(“Hello World! It’s me, thread #%ld!\n”, tid);
//pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t pid;
int rc;
long t;
while (1) {
printf(“In main: creating thread %ld\n”, t);
rc = pthread_create(&pid, NULL, PrintHello, NULL);
if (rc){
printf(“ERROR; return code from pthread_create() is %d\n”, rc);
//exit(-1);
}
sleep(1);
}
printf(” \n— main End —- \n”);
pthread_exit(NULL);
}
2. 在創(chuàng)建線程的設(shè)置PTHREAD_CREATE_DETACHED屬性
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *PrintHello(void)
{
int stack[1024 * 20] = {0,};
//pthread_exit(NULL);
//pthread_detach(pthread_self());
}
int main (int argc, char *argv[])
{
pthread_t pid;
int rc;
long t;
while (1) {
printf(“In main: creating thread %ld\n”, t);
pthread_attr_t attr;
pthread_t thread;
pthread_attr_init (&attr);
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
rc = pthread_create(&pid, &attr, PrintHello, NULL);
pthread_attr_destroy (&attr);
if (rc){
printf(“ERROR; return code from pthread_create() is %d\n”, rc);
//exit(-1);
}
sleep(1);
}
printf(” \n— main End —- \n”);
pthread_exit(NULL);
}
3. 創(chuàng)建線程后用 pthread_join() 一直等待子線程結(jié)束。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *PrintHello(void)
{
int stack[1024 * 20] = {0,};
//sleep(1);
long tid = 0;
//pthread_exit(NULL);
//pthread_detach(pthread_self());
}
int main (int argc, char *argv[])
{
pthread_t pid;
int rc;
long t;
while (1) {
printf(“In main: creating thread %ld\n”, t);
rc = pthread_create(&pid, NULL, PrintHello, NULL);
if (rc){
printf(“ERROR; return code from pthread_create() is %d\n”, rc);
//exit(-1);
}
pthread_join(pid, NULL);
sleep(1);
}
printf(” \n— main End —- \n”);
pthread_exit(NULL);
}