线程连接(joining)和分离(detaching)函数:
- pthread_join(threadid,status)
- pthread_detach(threadid,status)
- pthread_attr_setdetachstate(attr,detachstate)
- pthread_attr_getdetachstate(attr,detachstate)
pthread_join(threadid,status)——等待线程终止
语法:
#include <pthread.h>
int pthread_join(pthread_t thread, void ** value_ptr);
描述:
pthread_join()将挂起调用线程的执行直到目标线程终止,除非目标线程已经终止了。
在一次成功调用pthread_join()并有非NULL的参数value_ptr,传给pthread_exit()终止线程的这个值以value_ptr作为引用是可用的。
当pthread_join()成功返回,目标线程就会终止。
对同一目标线程多次同时调用pthread_join()的结果是不确定的。
如果调用pthread_join()的线程被取消,那么目标线程将不会被分离。
一个线程是否退出或者保持为连接状态不明确会与{PTHREAD_THREADS_MAX}相背。
(It is unspecified whether a thread that has exited but remains unjoined counts against {PTHREAD_THREADS_MAX}.)
返回值
如果执行成功,pthread_join()会返回0;否则,会返回错误代码以表明错误类型。
原理
pthread_join()函数在多线程应用程序中的便捷性是令人满意的。如果没有其他状态作为参数传给start_routine(),程序员可以模拟这个函数。
pthread_detach——分离线程
语法:
#include <pthread.h>
int pthread_detach(pthread_t thread);
描述:
pthread_detach()函数在所指出线程终止时,该线程的内存空间可以被回收。
如果线程没有终止,pthread_detach()函数也不会令其终止。
对同一目标线程多次调用pthread_datach()的结果是不确定的。
返回值:
如果调用成功,pthread_detach()返回0;反之,会返回错误代码表明错误。
原理:
每一个被创建的线程,最终都需要调用pthread_join()函数或者pthread_detach()函数,因为与线程相关联的内存空间需要回收。
我们建议调用分离函数是不必要的;把线程创建时的属性置为分离状态就足够了,因为线程永远不需要动态分离。但是,需要的话仅限于如下两个原因:
- 在用pthread_join()进行取消操作时,用pthread_detach()函数分离pthread_join()正在等待的线程是很必要的。没有它,就必须用pthread_join()去试图分离另一个线程,这样,会无限期的延误取消处理,并且会引入新的pthread_join()调用,而它本身有可能需要取消处理。
- 为了脱离“初始线程”(在进程中设立服务线程是一种可取的办法)。
连接:
“连接”是线程间完成同步的一种方法,例如:
pthread_join()过程阻塞调用线程,直到被指定的threadid线程终止;
程序员能够获得目标线程终止的返回状态,如果目标线程调用pthread_exit()时指定;
一个连接线程跟一个pthread_join()调用对应。如果对同一个线程进行多次连接会发生逻辑错误;
还有两个同步方法:互斥锁和条件变量。
是否连接?
当一个线程被创建了,它有一个属性表明了它是否可以被连接和分离。只有线程是可连接的(joinable)才可以被连接。如果一个线程作为分离来创建的,那么它永远不能被连接。
POSIX标准的最终方案线程被设计为可连接被创建;
为了明确创建线程的连接性和分离性,pthread_create()函数可使用attr参数。典型的4个步骤:
- 声明一个pthread_attr_t数据类型的pthread属性变量;
- 使用pthread_init()初始化属性变量;
- 使用pthread_attr_setdetachstate()设置属性为分离状态;
- 当使用完成后,使用pthread_attr_destroy()释放属性用到的资源。
分离
pthread_detach()函数能够明确的分离一个线程,即使被创建为可连接的。这个过程是不可逆的。
建议
- 如果一个线程需要连接,可以考虑创建时明确它是可连接的。这是因为可移动设备中并不是所有的实现,线程默认的是按照可连接创建的。
- 如果你预先知道一个线程永远不需要与另一个线程连接,可以考虑把它创建为分离状态。一些系统资源可能会因此而被释放。
参考资料
POSIX Threads Programming:https://computing.llnl.gov/tutorials/pthreads/#Joining