Pthread线程的资源的释放

来源:互联网 发布:ubuntu 自动安装依赖 编辑:程序博客网 时间:2024/04/29 22:20

线程的退出与其相关资源的释放

Pthread创建线程后必须使用join或detach释放线程资源;
首先说明一下几个函数的用法:

1.#include <pthread.h>
int pthread_create(pthread_t *restrict tidp,
                   const pthread_attr_t *restrict attr,
                   void *(*start_rtn)(void), 
                   void *restrict arg);
Returns: 0 if OK, error number on failure
第一个参数为指向线程标识符的指针。
第二个参数用来设置线程属性。
第三个参数是线程运行函数的起始地址。
最后一个参数是运行函数的参数。

2.pthread_self():函数用来获取当前调用该函数的线程的线程ID;
3.pthread_join():用来等待一个线程的结束。函数原型为:
 extern int pthread_join __P ((pthread_t __th, void **__thread_return));
 第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。
   这个函数是一个线程阻塞的函数,调用它的线程将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。一个线程的结束有两种途径,一种是象我们   上面的例子一样,函数结束了,调用它的线程也就结束了;另外一种就是调用函数pthread_exit。

    ①join是三种同步线程的方式之一。另外两种分别是互斥锁(mutex)和条件变量(condition variable)。 
    ②调用pthread_join()将阻塞自己,一直到要等待加入的线程运行结束。
    ③可以用pthread_join()获取线程的返回值。
    ④一个线程对应一个pthread_join()调用,对同一个线程进行多次pthread_join()调用是逻辑错误。


4.pthread_exit():它的函数原型为:
 extern void pthread_exit __P ((void *__retval)) __attribute__ ((__noreturn__));
 唯一的参数是函数的返回代码,只要pthread_exit中的参数retval不是NULL,这个值将被传递给thread_return。
  使用函数pthread_exit退出线程,这是线程的主动行为;

 ★最后要说明的是,一个线程不能被多个线程等待,否则第一个接收到信号的线程成功返回,其余调用pthread_join的线程则返回错误代码ESRCH。


linux线程执行和windows不同,pthread有两种状态joinable状态和unjoinable状态。
  一个线程默认的状态是joinable,如果线程是joinable状态,当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符

 (总计8K多)。只有当你调用了pthread_join之后这些资源才会被释放。

 若是unjoinable状态的线程,这些资源在线程函数退出时或pthread_exit时自动会被释放。unjoinable属性可以在pthread_create时指定,或在线程创建后在线程中 pthread_detach自己, 如:pthread_detach(pthread_self()),将状态改为unjoinable状态,确保资源的释放。

 如果线程状态为joinable,需要在之后适时调用pthread_join。

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


解决方法有三个:

1. 调用pthread_detach(pthread_self()),将状态改为unjoinable状态


2. 在创建线程的设置PTHREAD_CREATE_DETACHED属性,unjoinable属性可以在pthread_create时指定


3. 默认线程状态为joinable,需要创建线程后用 pthread_join()一直等待子线程结束,释放资源。


0 0
原创粉丝点击