c++ Pthread创建线程后必须使用join或detach释放线程资源

http://www.cppblog.com/prayer/archive/2012/04/23/172427.html

这两天在看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.)

也就是说:每个进程创建以后都应该调用pthread_join 或 pthread_detach 函数,只有这样在线程结束的时候资源(线程的描述信息和stack)才能被释放.

之后又查了pthread_join 但是没有明确说明必须调用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.

才知道如果在新线程里面没有调用pthread_join 或 pthread_detach会导致内存泄漏, 如果你创建的线程越多,你的内存利用率就会越高, 直到你再无法创建线程,最终只能结束进程。

解决方法有三个:

1.   线程里面调用 pthread_detach(pthread_self()) 这个方法最简单

2. 在创建线程的设置PTHREAD_CREATE_DETACHED属性

3. 创建线程后用 pthread_join() 一直等待子线程结束。

 

下面是几个简单的例子

1. 调用  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. 在创建线程的设置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. 创建线程后用 pthread_join() 一直等待子线程结束。

 

#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);

}

时间: 2024-10-28 20:32:29

c++ Pthread创建线程后必须使用join或detach释放线程资源的相关文章

课时3 线程启动、结束,创建线程多法,join、detach

用类作为可调用对象创建线程 class A { public: A() { cout << "构造函数" << endl; } A(const A& a) { cout << "拷贝构造函数" << endl; } void operator()() { cout << "此时在子线程中" << endl; } ~A() { cout << "析

C# WebService中任务处理线程创建子线程后

protected void WriteLog(string message) { lock (lockObject) { var file = System.IO.File.AppendText("C:\\log.txt"); file.WriteLine(message); file.Close(); } } protected void asyctest(int threadid) { this.WriteLog(string.Format("主线程({0})的子线程(

Java Thread.join()详解--父线程等待子线程结束后再结束

目录(?)[+] 阅读目录 一.使用方式. 二.为什么要用join()方法 三.join方法的作用 join 四.用实例来理解 打印结果: 打印结果: 五.从源码看join()方法 join是Thread类的一个方法,启动线程后直接调用,例如: ? 1 Thread t = new AThread(); t.start(); t.join(); 回到顶部 在很多情况下,主线程生成并起动了子线程,如果子线程里要进行大量的耗时的运算,主线程往往将于子线程之前结束,但是如果主线程处理完其他的事务后,需

7种创建线程方式,你知道几种?线程系列Thread(一)

前言 最近特别忙,博客就此荒芜,博主秉着哪里不熟悉就开始学习哪里的精神一直在分享着,有着扎实的基础才能写出茁壮的代码,有可能实现的逻辑有多种,但是心中必须有要有底哪个更适合,用着更好,否则则说明我们对这方面还比较薄弱,这个时候就得好好补补了,这样才能加快提升自身能力的步伐,接下来的时间会着重讲解线程方面的知识.强势分割线. 话题乱入,一到跳槽季节想必我们很多人就开始刷面试题,这种情况下大部分都能解决问题,但是这样的结果则是导致有可能企业招到并非合适的人,当然作为面试官的那些人们也懒得再去自己出一

join和 Daemon守护线程

一.前言 一个程序至少有一个主线程,主线程启动子线程后,它们之间并没有隶属关系.主线程和子线程执行是并行的,相互独立.主线程执行完毕后默认不等子线程执行结束就接着往下走了,如果有其他程序就会运行另外的程序,如果没有就等待子线程执行完成后结束程序. import threading import time import random class MyThread(threading.Thread): def __init__(self, n): super(MyThread, self).__in

Java总结(九)——(线程模块 一(线程的创建(方法一)与启动,线程状态与生命周期,进程与线程))

一.进程与线程 进程:每一个独立运行的程序称为一个进程 线程:线程时一个进程内部的一条执行路径,Java虚拟机允许程序并发的运行多个执行路径 *进程中执行运算的最小单位-->线程<--处理机分配 进程与线程的区别: (1)进程有独立的运行地址空间,一个进程崩溃后不会影响到其他的进程,而线程只是 一个进程中的一个执行路径,如果有一条线程奔溃了,可能会影响到进程中的的其他线程 (2)线程有自己的栈和局部变量,多个线程共享同一进程的地址空间 (3)一个进程至少有一个线程 多线程 (1)多线程 就是在

观察者模式实际应用:监听线程,意外退出线程后自动重启

摘要: 观察者模式,定义对象之间的一种一对多的依赖关系,当对象的状态发生改变时,所有依赖于它的对象都得到通知并且被自动更新.观察者模式在JDK中有现成的实现,java.util.Obserable. 首先说下需求:通过ftp上传约定格式的文件到服务器指定目录下,应用程序能实时监控该目录下文件变化,如果上传的文件格式符合要求,将将按照每一行读取解析再写入到数据库,解析完之后再将文件改名.(这个是原先已经实现了的功能,请看我的一篇文章java利用WatchService实时监控某个目录下的文件变化并

在不开启事件循环的线程中使用QTimer(QThread::run函数自带事件循环,在构造函数里创建线程,是一种很有意思的线程用法) good

引入 QTimer是Qt自带的定时器类,QTimer运行时是依赖于事件循环的,简单来说,在一个不开启事件循环(未调用exec() )的线程中,QTimer是无法使用的.通过分析Qt源码可发现,调用QTimer::start()后仅仅是在系统的定时器向量表中添加了一个定时器对象,但定时器并没有真正开启.定时器的开启需要通过processEvent()开始的一系列调用后才会真正得开启,这个过程中会处理定时器向量表中所有的定时器对象.那么实际exec()中也是在不断地调用processEvent()方

Thread的join的用法(线程执行排序)

此为转载解释: 线程必须要先start,才能join,只有启动了,才能对线程进行操作. 如有一个线程叫A,那么请看以下示例代码 A.start();   //启动A线程 A.join();   //邀请A线程先执行,本线程先暂停执行,等待A线程执行完后,主线程再接着往下执行 System.out.println("OK");   //这句话,要等到A线程执行完后,主线程获取到执行权后,才会被执行 具体例子: 代码段里,我把所有的join都注释掉了,输出的效果是 我把注释都打开join的