6.6.4 使用pthread属性对象
线程有一组属性是可以在线程被创建时指定的。该组属性被封装在一个对象中,该对象可用来设置一个或一组线程的属性。线程属性对象的类型为pthread_attr_t。这个结构体可用来设置这些线程属性:
线程栈的大小
线程栈的位置
调度继承机制、策略和参数
线程是否是分离的或可结合的
线程的范围
pthread_attr_t拥有一些方法来设置和获取这些属性。表6-3列出了用于设置属性的方法。
表6-3
|
属性函数的类型< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> |
pthread属性函数 |
|
初始化 |
pthread_attr_init( ) pthread_attr_destroy( ) |
|
栈管理 |
pthread_attr_setstacksize( ) pthread_attr_getstacksize( ) pthread_attr_setguardsize( ) pthread_attr_getguardsize( ) pthread_attr_setstack( ) pthread_attr_getstack( ) pthread_attr_setstackaddr( ) pthread_attr_getstackaddr( ) |
(续表)
|
属性函数的类型 |
pthread属性函数 |
|
分离状态 |
pthread_attr_setdetachstate( ) pthread_attr_getdetachstate( ) |
|
竞争范围 |
pthread_attr_setscope( ) pthread_attr_getscope( ) |
|
调度继承机制 |
pthread_attr_setinheritsched( ) pthread_attr_getinheritsched( ) |
|
调度策略 |
pthread_attr_setschedpolicy( ) pthread_attr_getschedpolicy( ) |
|
调度参数 |
pthread_attr_setschedparam( ) pthread_attr_getschedparam( ) |
pthread_attr_init( )和pthread_attr_destroy( )函数用于初始化和销毁线程属性对象。
调用形式
- #include <pthread.h>
- int pthread_attr_init(pthread_attr_t *attr);
- int pthread_attr_destroy(pthread_attr_t *attr);
pthread_attr_init( )使用默认值对线程属性对象的所有属性进行初始化。attr是指向pthread_attr_t对象的指针。一旦attr被初始化之后,它的属性值可以通过表6-3中列出的pthread_attr_set函数进行改变。一旦属性已经进行了适当的更改,则attr可用作任何对pthread_create( )函数的调用中的参数。如果函数调用成功,则返回0,如果调用没有成功,则函数返回错误号。如果没有足够的内存来创建对象,则pthread_attr_init( )函数失败。
pthread_attr_destroy( )函数可用于销毁由attr指定的pthread_attr_t对象。对这个函数的调用会删除所有同该线程属性对象相关联的隐藏的存储。如果成功,则函数返回0,如果失败,函数返回一个错误号。
1. 属性对象的默认值
属性对象首先会通过对所有个别属性使用给定实现所使用的默认值进行初始化。有些实现不支持某个属性的可能值。如果成功完成,则pthread_attr_init( )返回0。如果返回的是一个错误号,这可能意味着该值不被支持。例如,对于竞争范围,Linux环境不支持PTHREAD_SCOPE_PROCESS。调用:
- int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope);
会返回一个错误编码。表6-4列出了Linux和Solaris环境的默认值。
表6-4
|
pthread属性函数 |
SuSE Linux < xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /> |
Solaris 10的默认值 |
|
pthread_attr_ setdetachstate( ) |
PTHREAD_CREATE_JOINABLE |
PTHREAD_CREATE_JOINABLE |
|
pthread_attr_ setscope( ) |
PTHREAD_SCOPE_SYSTEM (PTHREAD_SCOPE_ PROCESS不被支持) |
PTHREAD_SCOPE_PROCESS |
|
pthread_attr_ setinheritsched( ) |
PTHREAD_EXPLICIT_SCHED |
PTHREAD_EXPLICIT_SCHED |
|
pthread_attr_ setschedpolicy( ) |
SCHED_OTHER |
SCHED_OTHER |
|
pthread_attr_ setschedparam( ) |
sched_priority = 0 |
sched_priority = 0 |
|
pthread_attr_ setstacksize( ) |
未指定 |
NULL 由系统分配 |
|
pthread_attr_ setstackaddr( ) |
未指定 |
NULL 1~2MB |
|
pthread_attr_ setguardsize( ) |
未指定 |
PAGESIZE |
2. 使用pthread线程对象创建分离的线程
在默认情况下,当线程退出时,操作系统在线程同另一个线程结合时保存线程的完成状态以及线程id。如果退出的线程不同其他线程结合,则称退出的线程是分离的(detached)。这种情况下不保存完成状态和线程id。在分离的线程上不能够使用pthread_join( )。如果使用了,则pthread_join( )返回一个错误。
调用形式
- #include <pthread.h>
- int pthread_attr_setdetachstate(pthread_attr_t *attr,
- int *detachstate);
- int pthread_attr_getdetachstate(const pthread_attr_t *attr,
- int *detachstate);
pthread_attr_setdetachstate( )函数可用于设置属性对象的detachstate属性。detachstate参数描述了线程是分离的还是可结合的。它可以为以下的值之一:
- PTHREAD_CREATE_DETACHED
- PTHREAD_CREATE_JOINABLE
值PTHREAD_CREATE_DETACHED使得所有使用这个属性对象的线程都被创建为分离的线程。值PTHREAD_CREATE_JOINABLE使得所有使用这个属性对象来创建的线程都被创建为可结合的线程。detachstate的默认值是PTHREAD_CREATE_JOINABLE。如果成功,则函数返回0;如果没有成功,函数返回一个错误号。如果detachstate的值无效,则函数pthread_attr_setdetachstate( )会失败。
函数pthread_attr_getdetachstate( )返回属性对象的detachstate。如果成功,则函数将detachstate的值返回给detachstate参数,并以0作为返回值。如果没有成功,则函数返回一个错误号。
已经在运行的线程也可以成为分离的。例如,线程可能不再对目标线程的结果感兴趣。线程可以分离,使得线程一旦退出,它的资源可以被收回。
调用形式
- int pthread_detach(pthread_t tid);
在示例6-2中,ThreadA是使用属性对象作为分离的线程创建的。ThreadB是在创建之后分离的。
示例6-2
- // Example 6-2 Using an attribute object to create a detached thread and changing
- // a joinable thread to a detached thread.
- //...
- int main(int argc, char *argv[])
- {
- pthread_t ThreadA,ThreadB;
- pthread_attr_t DetachedAttr;
- pthread_attr_init(&DetachedAttr);
- pthread_attr_setdetachstate(&DetachedAttr,PTHREAD_CREATE_DETACHED);
- pthread_create(&ThreadA,&DetachedAttr,task1,NULL);
- pthread_create(&ThreadB,NULL,task2,NULL);
- //...
- pthread_detach(pthread_t ThreadB);
- //pthread_join(ThreadB,NULL); cannot call once detached
- return (0);
- }
示例6-2声明了一个属性对象DetachedAttr。函数pthread_attr_init( )用来初始化属性对象。ThreadA是使用DetachedAttr属性对象创建的。这个属性对象已经将detachstate设置为PTHREAD_CREATE_DETACHED。ThreadB是使用detachstate的默认值,即PTHREAD_CREATE_JOINABLE来创建的。一旦创建完毕,就调用pthread_detech( )。既然ThreadB是分离的,就不能够为这个线程调用pthread_join( )。