线程创建
pthread_create()接口
使用pthread_create()来创建一个新的线程
线程属性
线程有自身的属性,属性类型为:pthread_attr_t,在使用pthread_create()接口创建线程时,可以通过设置线程属性对象的值,并作为创建线程的入参来设置新创建线程的属性。
在使用一个线程属性对象之前必须进行初始化,在使用后需要对其去除初始化。
pthread_attr_init()接口
调用pthread_attr_init之后,pthread_t结构所包含的内容就是操作系统实现支持的线程所有属性的默认值。
如果不想使用系统设置的默认线程属性值,可以调用pthread_attr_setxxx()系列接口设置自定义的值,例如:
使用pthread_attr_setdetachstate();来进行设置线程的分离状态。
使用pthread_attr_setscope();来进行设置线程的绑定状态。
使用pthread_attr_setstacksize;来设置创建新的线程时,系统分配的堆栈大小;如果不指定,创建线程时,系统将会使用默认值
查看默认值方法如下:
# ulimit -s
8192
#
上述表示为8M;单位为KB。
一般来说 默认堆栈大小为 8388608; 堆栈最小为 16384 。 单位为字节。
堆栈最小值定义为 PTHREAD_STACK_MIN ,包含#include <limits.h>后可以通过打印其值查看。对于默认值可以通过pthread_attr_getstacksize (&attr, &stack_size); 打印stack_size来查看。
尤其在嵌入式中内存不是很大,若采用默认值的话,会导致出现问题,若内存不足,则 pthread_create 会返回 12,定义如下:
#define ENOMEM 12 /* Out of memory */
一般在开辟新的线程时,新线程对资源要求不是特别高时就使用此接口设置自定义的堆栈值。
pthread_attr_destory()接口
如果要去除对pthread_attr_t结构的初始化,可以调用pthread_attr_destroy函数。如果pthread_attr_init实现时为属性对象分配了动态内存空间,pthread_attr_destroy还会释放动态内存,用无效的值初始化属性对象,因此如果经pthread_attr_destroy去除初始化之后的pthread_attr_t结构被pthread_create函数调用,将会导致其返回错误。man手册有介绍:
POSIX 标准要求:
When a thread attributes object is no longer required, it should be destroyed using the pthread_attr_destroy() function. Destroying a thread attributes object has no effect on threads that were created using that object.
当不再需要线程属性对象时,应该使用pthread_attr_destroy()函数销毁它。销毁线程属性对象对使用该对象创建的线程没有影响。
Once a thread attributes object has been destroyed, it can be reinitialized using pthread_attr_init(). Any othrer use of a destoryed thread attributes object has undefined results.
一旦线程属性对象被销毁,就可以使用它重新初始化pthread_attr_init()。任何对破坏线程属性对象的使用都有未定义的结果。
线程分离属性
线程分离状态决定线程终止的方法,线程的分离状态有分离线程和非分离线程两种。
1:线程在建立时没有使用设置线程属性对象,使用默认属性,默认终止方法是非分离状态,在这种情况下,需要使用pthread_join()接口阻塞等待线程结束,只有等pthread_join()函数返回时,线程才算终止。并且释放线程创建时系统给线程分配的堆栈资源。
非分离线程,在结束时如果不使用pthread_join()等待线程结束的话,线程所占用的资源不会得到释放,会造成资源泄露,这一点需要注意。
2:如果不想使用pthread_join()等待线程结束,手动回收线程资源,可以使用分离线程,分离线程不用其他线程等待,当前线程主函数运行完毕之后就结束了。并且马上自动释放资源。不需要使用pthread_join等待释放。
实现线程分离状态的几种方式:
(1):在创建线程的时候使用线程属性对象,自定义设置线程属性为分离状态:
pthread_attr_setdetachstate(&stAttr, PTHREAD_CREATE_DETACHED);
PTHREAD_CREATE_DETACHED--------------设置分离线程状态
pthread_attr_setdetachstate(&stAttr, PTHREAD_CREATE_JOINABLE)
PTHREAD_CREATE_JOINABLE------------------设置非分离线程状态--------默认状态
(2):在创建的子线程的主函数里面调用pthread_detach接口,将当前线程标记为分离状态
线程里面调用 pthread_detach(pthread_self()) 之后,线程可以自行分离。
注意:pthread_detach()接口只是控制线程终止之后所发生的事情,和设置线程属性为分离状态作用一样,而非何时或如何终止线程。