pthread_join与pthread_detach细节问题

http://www.360doc.com/content/13/0106/09/9171956_258497083.shtml

pthread_t    pthr;

pthread_create(&pthr, NULL, thread_handler, NULL);

...

void* thread_handler(void* arg)

{

/* do something */

pthread_join(pthr, NULL);

}

上面的代码不好使,pthread_join不能放在pthread调用的handler内,虽然不报错,但是thread无法正常回收,如果多次创建thread,内存会越来越大(另一种形式的内存泄露)。

正确的做法是在handler外面pthread_join:

pthread_t    pthr;

pthread_create(&pthr, NULL, thread_handler, NULL);

pthread_join(pthr, NULL);

...

void* thread_handler(void* arg)

{

/* do something */

}

如果不用pthread_join,改用pthread_detach呢?那最方便,但要注意:pthread_detach最好是放在handler里面第一句。

void* thread_handler(void* arg)

{

pthread_detach(pthr);

/* do something */

}

如果pthread_create后紧跟pthread_detach,有可能会出错。

pthread_detach(pthread_self())
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.

其实简单的说就是在线程函数头加上 pthread_detach(pthread_self())的话,线程状态改变,在函数尾部直接 pthread_exit线程就会自动退出。省去了给线程擦屁股的麻烦

pthread_self 
头文件
 #include <pthread.h> 
函数原型
 pthread_t pthread_self(void);

函数作用:获得线程自身的ID。pthread_t的类型为unsigned long int,所以在打印的时候要使用%lu方式,否则将产生奇怪的结果。
功能
 获取当前调用线程的 thread identifier(标识号).

近来发现 在线程函数第一行调用 pthread_detach(pthread_self()) 返回值是22不是0,后来在网上找到以下话语:

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。

时间: 2024-08-04 14:56:12

pthread_join与pthread_detach细节问题的相关文章

2线程原语:pthread_create(),pthread_self(),pthread_exit(),pthread_join(),pthread_cancel(),pthread_detach(

 1  pthread_create()函数 创建线程 A:依赖的头文件 #include<pthread.h> B:函数声明 int pthread_create(pthread_t *thread, constpthread_attr_t *attr, void *(*start_routine) (void *), void *arg); pthread_t *thread:传递一个pthread_t变量地址进来,用于保存新线程的tid(线程ID) const pthread_att

pthread_join和pthread_detach的用法

//从别处拷贝过来的,只作为自己查看方便,原作者不详,请谅解. 一:关于join join join是三种同步线程的方式之一.另外两种分别是互斥锁(mutex)和条件变量(condition variable). 调用pthread_join()将阻塞自己,一直到要等待加入的线程运行结束. 可以用pthread_join()获取线程的返回值. 一个线程对应一个pthread_join()调用,对同一个线程进行多次pthread_join()调用是逻辑错误. join or detach 线程分两

线程的控制与分离

线程的控制 线程的创建: 线程创建函数:int pthread_create(pthread_t *thread,const pthread_attr_t *attr,void *(*start_routine(void*),void *arg); 返回值:成功返回0,失败返回错误号. 在一个线程中调用pthread_create()创建新的线程后,当前线程从pthread_create()返回继续往下执行,而新的线程所执行的代码由我们传给pthread_create()的函数指针star_ro

Linux下线程的控制与分离

一.线程的概念: 线程是运行在进程地址空间的,是进程的执行分流.它是执行进程内部的一个代码片段为了让进程更好的完成.也可以说,进程是承担系统资源的实体,而线程进程运行调度的基本单位. 由于同一进程的多个线程共享同一地址空间,因此Text Segment.Data Segment都是共享的,如果定义一个函数,在各线程中都可以调用,如果定义一个全局变量,在各线程中都可以访问到,除此之外,各线程还共享以下进程资源和环境: 1. 文件描述符表 2. 每种信号的处理方式(SIG_IGN.SIG_DFL或者

linux环境下的线程的创建问题

pthread_create函数用于创建一个线程 函数原型 #include<pthread.h> int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg); 参数与返回值 tidp:类型为pthread_t的指针,当pthread_create成功返回时,该函数将线程ID存储在tidp指向的内

c++ thread

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 bereleased. (But note that the resources of all threads are freed when the process terminates.)也就是说:每

Windows 和 Linux 的IPC API对应表

原文出处:http://blog.csdn.net/zhengdy/article/details/5485472                                              Windows 和 Linux 的IPC API对应表 Table 1. Process mapping Windows Linux Classification CreateProcess() CreateProcessAsUser() fork() setuid() exec() Mapp

life of a NPTL pthread

这是2013年写的一篇旧文,放在gegahost.net上面 http://raison.gegahost.net/?p=91 March 7, 2013 life of a NPTL pthread Filed under: concurrency,linux,posix — Tags: NPTL, pthread — Raison @ 12:52 pm (Original Work by Peixu Zhu) NPTL pthread is the default pthread imple

线程与线程控制

原文链接:http://www.orlion.ga/1250/ 一.线程 同一进程的多个线程共享同一地址空间,因此Text Segment.Data Segment都是共享的,如果定义一个函数,在个线程中都可以调用,如果定义一个全局变量,在各线程中都可以访问到,除此之外,个线程还共享一下进程资源和环境: 文件描述符 每种信号的处理方式(SIG_IGN.SIG_DFL或者自定义的信号处理函数) 当前工作目录 用户id和组id 但有些资源使每个线程各有一份的: 线程id 上下文,包括各种寄存器的值.