首页 > 代码库 > 《UNIX环境高级编程》读书笔记之线程(2)
《UNIX环境高级编程》读书笔记之线程(2)
1.线程属性
可以使用pthread_attr_t结构来指定线程的属性,并把这些属性与线程联系起来。可以使用pthread_attr_init函数来初始化pthread_attr_t对象为系统线程属性的默认值。
下图给定了各系统中定义的线程属性。
如果对线程的终止状态不感兴趣,可以修改pthread_attr_t结构中的detachstate属性,让线程一开始就处于分离状态,可以采用pthread_attr_setdetachstate(const pthread_attr_t *restrict attr,int * detachstate)更改pthread_attr_t结构的属性。
可以通过pthread_attr_getstack函数和pthread_attr_setstack函数来对线程的栈属性进行管理。
其中stackaddr代表栈的最低地址,stacksize代表栈的大小。
如果希望改变默认栈的大小,又不想处理线程栈的分配问题,这时用pthread_attr_setstacksize就很合适。选择stack_size时,stack_size不能小于PTHREAD_STACK_MIN。
有两个线程的属性没有包含在pthread_attr_t结构中,它们是可取消状态和可取消类型。
可取消状态可以是PTHREAD_CANCEL_ENABLE,也可以是PTHREAD_CANCEL_DISABLE。线程可以通过pthread_setcancelstate修改它的可取消状态。线程启动时默认的可取消状态时ENABLE的。当状态为DISABLE时,对线程调用pthread_cancel的调用并不会杀死线程。这时取消请求对这个线程来说还处于挂起状态,当取消状态再次变为PTHREAD_CANCEL_ENABLE时,线程将在下一个取消点上对挂起的取消请求进行处理(在默认情况下,线程在取消请求发出后还是会继续运行,直到线程到达某个取消点)。
系统默认的取消类型是推迟取消,即达到取消点之后才会真正取消线程。我们可以通过pthread_setcanceltype来设置取消的类型。可选的类型有PTHREAD_CANCEL_DEFERRED,PTHREAD_CANCEL_ASYNCHRONOUS。当选用PTHREAD_CANCEL_ASYNCHRONOUS时,线程可以再任一时刻取消,而不用等到取消点。
2.互斥量属性
互斥量属性是用pthread_mutexattr_t结构表示的。它值得注意的三个属性是:进程共享属性,健壮属性以及类型属性。
(1)进程共享属性
在进程共享数据时都需要进行同步。当进程共享互斥量属性设置为PTHREAD_PROCESS_SHARED时,它就可以用于这些进程的同步。
使用pthread_mutexattr_getshared函数得到共享属性,适用pthread_mutexattr_setshared函数来设置共享属性。
(2)健壮性
互斥量健壮性属性与多个进程之间共享互斥量有关。这意味着当持有互斥量的进程终止时,要解决互斥量状态恢复的问题。
健壮属性取值有两个不同的可能。默认值是PTHREAD_MUTEX_STALLED,这意味着持有互斥量的进程在终止时不需要采取额外的措施。在这种情况下,使用互斥量后的行为是未定义的,等待该互斥量解锁的应用程序会被拖住。另一个取值是PTHREAD_MUTEX_ROBUST。当互斥量的健壮性设置为PTHREAD_MUTEX_ROBUST时,如果线程调用pthread_mutex_lock获取锁,且该锁被另外一个进程持有,但进程终止时并没有释放锁,此时线程会阻塞,但返回值会是EOWNERDEAD而不是0。
(3)类型属性
POSIX.1定义了四种类型:(1)PTHREAD_MUTEX_NORMAL:一种标准互斥量类型,不做任何错误检测。(2)PTHREAD_MUTEX_ERRORCHECK:对不合理的操作提供错误检查。(3)PTHREAD_MUTEX_RECURSIVE:允许在一个互斥量还没有释放的情况下对该互斥量多次加锁。(4)PTHREAD_MUTEX_DEFAULT :提供默认的行为,操作系统实现它时把它映射到其他互斥量中的一种。
这四种类型的行为下图所示:
不占用是解锁表示一个线程对其他线程的互斥量进行解锁时的情况,在已解锁时解锁表示一个线程对已经解锁的互斥量进行解锁时的情况。
可以通过pthread_mutexattr_gettype函数和pthread_mutexattr_settype函数来管理互斥量的类型。
3.读写锁属性
读写锁支持的唯一属性是进程共享属性,它与互斥量的进程共享属性是相同的,可以通过相应的get和set函数进行操作。
4.屏障属性
屏障支持的唯一属性是进程共享属性,它与互斥量的进程共享属性是相同的,可以通过相应的get和set函数进行操作。
《UNIX环境高级编程》读书笔记之线程(2)