pthread_join和pthread_detach

转载自:http://blog.csdn.net/u014774781/article/details/48039441
在任何一个时间点上,线程是可结合的(joinable)或者是分离的(detached)。一个可结合的线程能够被其他线程收回其资源和杀死。在被其他线程回收之前,它的存储器资源(例如栈)是不释放的。相反,一个分离的线程是不能被其他线程回收或杀死的,它的存储器资源在它终止时由系统自动释放。默认情况下,线程被创建成可结合的。为了避免存储器泄漏,每个可结合线程都应该要么被显示地回收,即调用pthread_join;要么通过调用pthread_detach函数被分离。

pthread_join函数等待其他线程终止。pthread_join函数分阻塞,直到线程tid终止,将线程例程返回的(void*)指针赋值为thread_return指向的位置,然后回收已终止线程占用的所有存储器资源。
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),如此一来,该线程运行结束后会自动释放所有资源。

#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);

pthread_join()函数等待thread指定的线程终止。 如果该线程已经终止,则pthread_join()立即返回。 由thread指定的线程必须可以连接。
如果retval不为NULL,则pthread_join()将目标线程的退出状态(即目标线程提供给pthread_exit()的值)复制到* retval所指向的位置。 如果目标线程被取消,则PTHREAD_CANCELED被放置在* retval中。
如果多个线程同时尝试使用同一个线程进行连接,则结果是不确定的。 如果调用pthread_join()的线程被取消,那么目标线程将保持可连接(即,它不会被分离)。
成功时,pthread_join()返回0; 错误时,它返回一个错误号。
错误:
EDEADLK:检测到死锁(例如,两个线程试图彼此连接); 或者thread指定调用线程。
EINVAL:thread不是可连接的线程。
EINVAL:另一个线程已经在等待加入此线程。
ESRCH:不能找到ID thread的线程。

在成功调用pthread_join()之后,调用者保证目标线程已经终止。
加入之前已加入的线程会导致未定义的行为。
如果未能加入可联结的线程(即未联结的线程),会产生一个“僵尸线程”。避免这样做,因为每个僵尸线程都会消耗一些系统资源,并且当足够多的僵尸线程累积时,它将不会 更长的时间才能创建新的线程(或进程)。waitpid(-1,&status,0)没有pthreads模拟,即“加入任何终止的线程”。 如果您认为您需要此功能,则可能需要重新考虑您的应用程序设计。
进程中的所有线程都是对等的:任何线程都可以与进程中的任何其他线程连接。

猜你喜欢

转载自blog.csdn.net/qq_38365116/article/details/79369205